diff --git a/.bruno/Payment/account/create.bru b/.bruno/Payment/account/create.bru
deleted file mode 100644
index 7a4bf7a..0000000
--- a/.bruno/Payment/account/create.bru
+++ /dev/null
@@ -1,24 +0,0 @@
-meta {
- name: Create
- type: http
- seq: 1
-}
-
-post {
- url: {{url}}/payment/wallets
- body: json
- auth: inherit
-}
-
-body:json {
- {
- "ledgerId": "ee228d0d-b48c-4878-aca3-050a7434503b",
- "entityId": "some-external-entity",
- "label": "Securities"
- }
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/account/folder.bru b/.bruno/Payment/account/folder.bru
deleted file mode 100644
index 109fad9..0000000
--- a/.bruno/Payment/account/folder.bru
+++ /dev/null
@@ -1,4 +0,0 @@
-meta {
- name: Wallet
- seq: 3
-}
diff --git a/.bruno/Payment/beneficiary/Ledgers.bru b/.bruno/Payment/beneficiary/Ledgers.bru
deleted file mode 100644
index 3297d88..0000000
--- a/.bruno/Payment/beneficiary/Ledgers.bru
+++ /dev/null
@@ -1,20 +0,0 @@
-meta {
- name: Ledgers
- type: http
- seq: 5
-}
-
-get {
- url: {{url}}/payment/beneficiaries/:id/ledgers
- body: json
- auth: inherit
-}
-
-params:path {
- id: 16f41847-4bc4-4898-92d1-75fd314d15a8
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/beneficiary/create.bru b/.bruno/Payment/beneficiary/create.bru
deleted file mode 100644
index fe7b85d..0000000
--- a/.bruno/Payment/beneficiary/create.bru
+++ /dev/null
@@ -1,23 +0,0 @@
-meta {
- name: Create
- type: http
- seq: 1
-}
-
-post {
- url: {{url}}/payment/beneficiaries
- body: json
- auth: inherit
-}
-
-body:json {
- {
- "tenantId": "valkyr-inc",
- "label": "Valkyr Inc."
- }
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/beneficiary/dashboard.bru b/.bruno/Payment/beneficiary/dashboard.bru
deleted file mode 100644
index 84ff776..0000000
--- a/.bruno/Payment/beneficiary/dashboard.bru
+++ /dev/null
@@ -1,20 +0,0 @@
-meta {
- name: Dashboard
- type: http
- seq: 2
-}
-
-get {
- url: {{url}}/payment/dashboard/:id
- body: json
- auth: inherit
-}
-
-params:path {
- id: 16f41847-4bc4-4898-92d1-75fd314d15a8
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/beneficiary/folder.bru b/.bruno/Payment/beneficiary/folder.bru
deleted file mode 100644
index 31faaa3..0000000
--- a/.bruno/Payment/beneficiary/folder.bru
+++ /dev/null
@@ -1,4 +0,0 @@
-meta {
- name: Beneficiary
- seq: 1
-}
diff --git a/.bruno/Payment/beneficiary/id.bru b/.bruno/Payment/beneficiary/id.bru
deleted file mode 100644
index 9026f9b..0000000
--- a/.bruno/Payment/beneficiary/id.bru
+++ /dev/null
@@ -1,20 +0,0 @@
-meta {
- name: :id
- type: http
- seq: 4
-}
-
-get {
- url: {{url}}/payment/beneficiaries/:id
- body: json
- auth: inherit
-}
-
-params:path {
- id: a0a6aa39-5d13-4717-9554-a878d7f30ea7
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/beneficiary/list.bru b/.bruno/Payment/beneficiary/list.bru
deleted file mode 100644
index 3eac0d2..0000000
--- a/.bruno/Payment/beneficiary/list.bru
+++ /dev/null
@@ -1,16 +0,0 @@
-meta {
- name: List
- type: http
- seq: 3
-}
-
-get {
- url: {{url}}/payment/beneficiaries
- body: json
- auth: inherit
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/folder.bru b/.bruno/Payment/folder.bru
deleted file mode 100644
index 366e4fe..0000000
--- a/.bruno/Payment/folder.bru
+++ /dev/null
@@ -1,4 +0,0 @@
-meta {
- name: Payment
- seq: 2
-}
diff --git a/.bruno/Payment/ledger/create.bru b/.bruno/Payment/ledger/create.bru
deleted file mode 100644
index 27bd308..0000000
--- a/.bruno/Payment/ledger/create.bru
+++ /dev/null
@@ -1,27 +0,0 @@
-meta {
- name: Create
- type: http
- seq: 1
-}
-
-post {
- url: {{url}}/payment/ledgers
- body: json
- auth: inherit
-}
-
-body:json {
- {
- "beneficiaryId": "16f41847-4bc4-4898-92d1-75fd314d15a8",
- "label": "Sample Ledger #1",
- "currencies": [
- "NOK",
- "SEK"
- ]
- }
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/ledger/folder.bru b/.bruno/Payment/ledger/folder.bru
deleted file mode 100644
index 0e9edbe..0000000
--- a/.bruno/Payment/ledger/folder.bru
+++ /dev/null
@@ -1,4 +0,0 @@
-meta {
- name: Ledger
- seq: 2
-}
diff --git a/.bruno/Payment/ledger/wallets.bru b/.bruno/Payment/ledger/wallets.bru
deleted file mode 100644
index 0696533..0000000
--- a/.bruno/Payment/ledger/wallets.bru
+++ /dev/null
@@ -1,20 +0,0 @@
-meta {
- name: Wallets
- type: http
- seq: 3
-}
-
-get {
- url: {{url}}/payment/ledgers/:id/wallets
- body: json
- auth: inherit
-}
-
-params:path {
- id: 3c71d240-a375-42e1-9a78-0575bf33fabb
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/wallet/create.bru b/.bruno/Payment/wallet/create.bru
deleted file mode 100644
index 5d5e834..0000000
--- a/.bruno/Payment/wallet/create.bru
+++ /dev/null
@@ -1,24 +0,0 @@
-meta {
- name: Create
- type: http
- seq: 1
-}
-
-post {
- url: {{url}}/payment/accounts
- body: json
- auth: inherit
-}
-
-body:json {
- {
- "walletId": "c13bd907-d760-4628-95e8-a723a54dff83",
- "currency": "NOK",
- "label": "Sample Funds"
- }
-}
-
-settings {
- encodeUrl: true
- timeout: 0
-}
diff --git a/.bruno/Payment/wallet/folder.bru b/.bruno/Payment/wallet/folder.bru
deleted file mode 100644
index 7bcba0a..0000000
--- a/.bruno/Payment/wallet/folder.bru
+++ /dev/null
@@ -1,4 +0,0 @@
-meta {
- name: Account
- seq: 4
-}
diff --git a/.bruno/bruno.json b/.bruno/bruno.json
deleted file mode 100644
index b2c9a3a..0000000
--- a/.bruno/bruno.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "version": "1",
- "name": "Valkyr",
- "type": "collection",
- "ignore": [
- "node_modules",
- ".git"
- ]
-}
\ No newline at end of file
diff --git a/.bruno/environments/localhost.bru b/.bruno/environments/localhost.bru
deleted file mode 100644
index 1f2c42d..0000000
--- a/.bruno/environments/localhost.bru
+++ /dev/null
@@ -1,3 +0,0 @@
-vars {
- url: http://localhost:8370/api/v1
-}
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 0425ac9..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "biome.enabled": true,
- "deno.enable": true,
- "deno.lint": false,
- "editor.defaultFormatter": "biomejs.biome",
- "editor.formatOnSave": true,
- "editor.codeActionsOnSave": {
- "source.organizeImports.biome": "explicit",
- "source.fixAll.biome": "explicit"
- },
- "files.readonlyInclude": {
- "**/routeTree.gen.ts": true
- },
- "files.watcherExclude": {
- "**/routeTree.gen.ts": true
- },
- "search.exclude": {
- "**/routeTree.gen.ts": true
- },
- "files.exclude": {
- "**/.git": true,
- "**/.svn": true,
- "**/.hg": true,
- "**/CVS": true,
- "**/.DS_Store": true,
- "**/Thumbs.db": true
- }
-}
diff --git a/Dockerfile b/Dockerfile
index 398d47c..c3e002b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM denoland/deno:2.5.1
+FROM denoland/deno:2.6.4
ENV TZ=UTC
ENV PORT=8370
@@ -8,10 +8,11 @@ EXPOSE 8370
WORKDIR /app
COPY api/ ./api/
-COPY relay/ ./relay/
+COPY modules/ ./modules/
+COPY platform/ ./platform/
COPY .npmrc .
-COPY deno-docker.json ./deno.json
+COPY deno.json ./deno.json
RUN deno install --allow-scripts
-CMD ["sh", "-c", "deno run --allow-all ./api/.tasks/migrate.ts && deno run --allow-all ./api/server.ts"]
\ No newline at end of file
+CMD ["sh", "-c", "deno run --allow-all ./api/.tasks/migrate.ts && deno run --allow-all ./api/server.ts"]
diff --git a/apps/README.md b/apps/README.md
deleted file mode 100644
index c7782ba..0000000
--- a/apps/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Apps
\ No newline at end of file
diff --git a/apps/react/.gitignore b/apps/react/.gitignore
deleted file mode 100644
index a547bf3..0000000
--- a/apps/react/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/apps/react/.npmrc b/apps/react/.npmrc
deleted file mode 100644
index 41583e3..0000000
--- a/apps/react/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-@jsr:registry=https://npm.jsr.io
diff --git a/apps/react/README.md b/apps/react/README.md
deleted file mode 100644
index 7959ce4..0000000
--- a/apps/react/README.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# React + TypeScript + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-
-Currently, two official plugins are available:
-
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
-
-## Expanding the ESLint configuration
-
-If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
-
-```js
-export default tseslint.config([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
-
- // Remove tseslint.configs.recommended and replace with this
- ...tseslint.configs.recommendedTypeChecked,
- // Alternatively, use this for stricter rules
- ...tseslint.configs.strictTypeChecked,
- // Optionally, add this for stylistic rules
- ...tseslint.configs.stylisticTypeChecked,
-
- // Other configs...
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
-```
-
-You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
-
-```js
-// eslint.config.js
-import reactX from 'eslint-plugin-react-x'
-import reactDom from 'eslint-plugin-react-dom'
-
-export default tseslint.config([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
- // Enable lint rules for React
- reactX.configs['recommended-typescript'],
- // Enable lint rules for React DOM
- reactDom.configs.recommended,
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
-```
diff --git a/apps/react/components.json b/apps/react/components.json
deleted file mode 100644
index c3a0a52..0000000
--- a/apps/react/components.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
- "rsc": false,
- "tsx": true,
- "tailwind": {
- "config": "tailwind.config.js",
- "css": "src/index.css",
- "baseColor": "neutral",
- "cssVariables": true,
- "prefix": ""
- },
- "iconLibrary": "lucide",
- "aliases": {
- "components": "@/components",
- "utils": "@/libraries/utils",
- "ui": "@/components/ui",
- "lib": "@/libraries",
- "hooks": "@/hooks"
- },
- "registries": {}
-}
diff --git a/apps/react/index.html b/apps/react/index.html
deleted file mode 100644
index acd2f9c..0000000
--- a/apps/react/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
- Vite + React + TS
-
-
-
-
-
-
diff --git a/apps/react/package.json b/apps/react/package.json
deleted file mode 100644
index c9904fb..0000000
--- a/apps/react/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "name": "react",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc -b && vite build",
- "lint": "eslint .",
- "preview": "vite preview"
- },
- "dependencies": {
- "@module/account": "workspace:*",
- "@platform/relay": "workspace:*",
- "@platform/spec": "workspace:*",
- "@radix-ui/react-avatar": "^1.1.11",
- "@radix-ui/react-dialog": "^1.1.15",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@radix-ui/react-label": "^2.1.8",
- "@radix-ui/react-scroll-area": "^1.2.10",
- "@radix-ui/react-separator": "^1.1.8",
- "@radix-ui/react-slot": "^1.2.4",
- "@radix-ui/react-tooltip": "^1.2.8",
- "@tabler/icons-react": "3.35.0",
- "@tanstack/react-query": "5.89.0",
- "@tanstack/react-router": "1.131.47",
- "@valkyr/db": "npm:@jsr/valkyr__db@2.0.0",
- "@valkyr/event-emitter": "npm:@jsr/valkyr__event-emitter@1.0.1",
- "@zitadel/react": "1.1.0",
- "class-variance-authority": "^0.7.1",
- "clsx": "^2.1.1",
- "fast-equals": "5.2.2",
- "lucide-react": "^0.554.0",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "tailwind-merge": "^3.4.0",
- "tailwindcss": "4.1.13",
- "tailwindcss-animate": "^1.0.7",
- "tw-animate-css": "1.4.0",
- "zod": "4.3.5"
- },
- "devDependencies": {
- "@eslint/js": "9.35.0",
- "@tailwindcss/vite": "4.1.13",
- "@tanstack/react-router-devtools": "1.131.47",
- "@types/react": "^19.2.7",
- "@types/react-dom": "^19.2.3",
- "@vitejs/plugin-react": "4.7.0",
- "eslint": "9.35.0",
- "eslint-plugin-react-hooks": "5.2.0",
- "eslint-plugin-react-refresh": "0.4.20",
- "globals": "16.4.0",
- "typescript": "5.9.2",
- "typescript-eslint": "8.44.0",
- "vite": "7.1.6"
- }
-}
diff --git a/apps/react/public/vite.svg b/apps/react/public/vite.svg
deleted file mode 100644
index e7b8dfb..0000000
--- a/apps/react/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/react/src/adapters/http.ts b/apps/react/src/adapters/http.ts
deleted file mode 100644
index 33fa288..0000000
--- a/apps/react/src/adapters/http.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-import {
- assertServerErrorResponse,
- type RelayAdapter,
- type RelayInput,
- type RelayResponse,
- ServerError,
- type ServerErrorResponse,
- type ServerErrorType,
-} from "@platform/relay";
-
-/**
- * HttpAdapter provides a unified transport layer for Relay.
- *
- * It supports sending JSON objects, nested structures, arrays, and file uploads
- * via FormData. The adapter automatically detects the payload type and formats
- * the request accordingly. Responses are normalized into `RelayResponse`.
- *
- * @example
- * ```ts
- * const adapter = new HttpAdapter({ url: "https://api.example.com" });
- *
- * // Sending JSON data
- * const jsonResponse = await adapter.send({
- * method: "POST",
- * endpoint: "/users",
- * body: { name: "Alice", age: 30 },
- * });
- *
- * // Sending files and nested objects
- * const formResponse = await adapter.send({
- * method: "POST",
- * endpoint: "/upload",
- * body: {
- * user: { name: "Bob", avatar: fileInput.files[0] },
- * documents: [fileInput.files[1], fileInput.files[2]],
- * },
- * });
- * ```
- */
-export class HttpAdapter implements RelayAdapter {
- /**
- * Instantiate a new HttpAdapter instance.
- *
- * @param options - Adapter options.
- */
- constructor(readonly options: HttpAdapterOptions) {}
-
- /**
- * Override the initial url value set by instantiator.
- */
- set url(value: string) {
- this.options.url = value;
- }
-
- /**
- * Retrieve the URL value from options object.
- */
- get url() {
- return this.options.url;
- }
-
- /**
- * Return the full URL from given endpoint.
- *
- * @param endpoint - Endpoint to get url for.
- */
- getUrl(endpoint: string): string {
- return `${this.url}${endpoint}`;
- }
-
- async send({ method, endpoint, query, body, headers = new Headers() }: RelayInput): Promise {
- const init: RequestInit = { method, headers };
-
- // ### Before Request
- // If any before request hooks has been defined, we run them here passing in the
- // request headers for further modification.
-
- await this.#beforeRequest(headers);
-
- // ### Body
-
- if (body !== undefined) {
- const type = this.#getRequestFormat(body);
- if (type === "form-data") {
- headers.delete("content-type");
- init.body = this.#getFormData(body);
- }
- if (type === "json") {
- headers.set("content-type", "application/json");
- init.body = JSON.stringify(body);
- }
- }
-
- // ### Response
-
- return this.request(`${endpoint}${query}`, init);
- }
-
- /**
- * Send a fetch request using the given fetch options and returns
- * a relay formatted response.
- *
- * @param endpoint - Which endpoint to submit request to.
- * @param init - Request init details to submit with the request.
- */
- async request(endpoint: string, init?: RequestInit): Promise {
- return this.#toResponse(await fetch(this.getUrl(endpoint), init));
- }
-
- /**
- * Run before request operations.
- *
- * @param headers - Headers to pass to hooks.
- */
- async #beforeRequest(headers: Headers) {
- if (this.options.hooks?.beforeRequest !== undefined) {
- for (const hook of this.options.hooks.beforeRequest) {
- await hook(headers);
- }
- }
- }
-
- /**
- * Determine the parser method required for the request.
- *
- * @param body - Request body.
- */
- #getRequestFormat(body: unknown): "form-data" | "json" {
- if (containsFile(body) === true) {
- return "form-data";
- }
- return "json";
- }
-
- /**
- * Get FormData instance for the given body.
- *
- * @param body - Request body.
- */
- #getFormData(data: Record, formData = new FormData(), parentKey?: string): FormData {
- for (const key in data) {
- const value = data[key];
- if (value === undefined || value === null) continue;
-
- const formKey = parentKey ? `${parentKey}[${key}]` : key;
-
- if (value instanceof File) {
- formData.append(formKey, value, value.name);
- } else if (Array.isArray(value)) {
- value.forEach((item, index) => {
- if (item instanceof File) {
- formData.append(`${formKey}[${index}]`, item, item.name);
- } else if (typeof item === "object") {
- this.#getFormData(item as Record, formData, `${formKey}[${index}]`);
- } else {
- formData.append(`${formKey}[${index}]`, String(item));
- }
- });
- } else if (typeof value === "object") {
- this.#getFormData(value as Record, formData, formKey);
- } else {
- formData.append(formKey, String(value));
- }
- }
-
- return formData;
- }
-
- /**
- * Convert a fetch response to a compliant relay response.
- *
- * @param response - Fetch response to convert.
- */
- async #toResponse(response: Response): Promise {
- const type = response.headers.get("content-type");
-
- // ### Content Type
- // Ensure that the server responds with a 'content-type' definition. We should
- // always expect the server to respond with a type.
-
- if (type === null) {
- return {
- result: "error",
- error: {
- status: response.status,
- message: "Missing 'content-type' in header returned from server.",
- },
- };
- }
-
- // ### Empty Response
- // If the response comes back with empty response status 204 we simply return a
- // empty success.
-
- if (response.status === 204) {
- return {
- result: "success",
- data: null,
- };
- }
-
- // ### JSON
- // If the 'content-type' contains 'json' we treat it as a 'json' compliant response
- // and attempt to resolve it as such.
-
- if (type.includes("json") === true) {
- const parsed = await response.json();
- if ("data" in parsed) {
- return {
- result: "success",
- data: parsed.data,
- };
- }
- if ("error" in parsed) {
- return {
- result: "error",
- error: this.#toError(parsed),
- };
- }
- return {
- result: "error",
- error: {
- status: response.status,
- message: "Unsupported 'json' body returned from server, missing 'data' or 'error' key.",
- },
- };
- }
-
- return {
- result: "error",
- error: {
- status: response.status,
- message: "Unsupported 'content-type' in header returned from server.",
- },
- };
- }
-
- #toError(candidate: unknown, status: number = 500): ServerErrorType | ServerErrorResponse["error"] {
- if (assertServerErrorResponse(candidate)) {
- return ServerError.fromJSON({ type: "relay", ...candidate.error });
- }
- if (typeof candidate === "string") {
- return {
- status,
- message: candidate,
- };
- }
- return {
- status,
- message: "Unsupported 'error' returned from server.",
- };
- }
-}
-
-function containsFile(value: unknown): boolean {
- if (value instanceof File) {
- return true;
- }
- if (Array.isArray(value)) {
- return value.some(containsFile);
- }
- if (typeof value === "object" && value !== null) {
- return Object.values(value).some(containsFile);
- }
- return false;
-}
-
-export type HttpAdapterOptions = {
- url: string;
- hooks?: {
- beforeRequest?: ((headers: Headers) => Promise)[];
- };
-};
diff --git a/apps/react/src/assets/react.svg b/apps/react/src/assets/react.svg
deleted file mode 100644
index 6c87de9..0000000
--- a/apps/react/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/react/src/components/app-sidebar.tsx b/apps/react/src/components/app-sidebar.tsx
deleted file mode 100644
index 3952ec0..0000000
--- a/apps/react/src/components/app-sidebar.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-"use client";
-
-import {
- IconCamera,
- IconChartBar,
- IconDashboard,
- IconDatabase,
- IconFileAi,
- IconFileDescription,
- IconFileWord,
- IconFolder,
- IconHelp,
- IconInnerShadowTop,
- IconListDetails,
- IconReport,
- IconSearch,
- IconSettings,
- IconUsers,
-} from "@tabler/icons-react";
-import type * as React from "react";
-
-import { NavDocuments } from "@/components/nav-documents";
-import { NavMain } from "@/components/nav-main";
-import { NavSecondary } from "@/components/nav-secondary";
-import { NavUser } from "@/components/nav-user";
-import {
- Sidebar,
- SidebarContent,
- SidebarFooter,
- SidebarHeader,
- SidebarMenu,
- SidebarMenuButton,
- SidebarMenuItem,
-} from "@/components/ui/sidebar";
-
-const data = {
- user: {
- name: "shadcn",
- email: "m@example.com",
- avatar: "/avatars/shadcn.jpg",
- },
- navMain: [
- {
- title: "Dashboard",
- url: "#",
- icon: IconDashboard,
- },
- {
- title: "Lifecycle",
- url: "#",
- icon: IconListDetails,
- },
- {
- title: "Analytics",
- url: "#",
- icon: IconChartBar,
- },
- {
- title: "Projects",
- url: "#",
- icon: IconFolder,
- },
- {
- title: "Team",
- url: "#",
- icon: IconUsers,
- },
- ],
- navClouds: [
- {
- title: "Capture",
- icon: IconCamera,
- isActive: true,
- url: "#",
- items: [
- {
- title: "Active Proposals",
- url: "#",
- },
- {
- title: "Archived",
- url: "#",
- },
- ],
- },
- {
- title: "Proposal",
- icon: IconFileDescription,
- url: "#",
- items: [
- {
- title: "Active Proposals",
- url: "#",
- },
- {
- title: "Archived",
- url: "#",
- },
- ],
- },
- {
- title: "Prompts",
- icon: IconFileAi,
- url: "#",
- items: [
- {
- title: "Active Proposals",
- url: "#",
- },
- {
- title: "Archived",
- url: "#",
- },
- ],
- },
- ],
- navSecondary: [
- {
- title: "Settings",
- url: "#",
- icon: IconSettings,
- },
- {
- title: "Get Help",
- url: "#",
- icon: IconHelp,
- },
- {
- title: "Search",
- url: "#",
- icon: IconSearch,
- },
- ],
- documents: [
- {
- name: "Data Library",
- url: "#",
- icon: IconDatabase,
- },
- {
- name: "Reports",
- url: "#",
- icon: IconReport,
- },
- {
- name: "Word Assistant",
- url: "#",
- icon: IconFileWord,
- },
- ],
-};
-
-export function AppSidebar({ ...props }: React.ComponentProps) {
- return (
-
-
-
-
-
-
-
- Acme Inc.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/react/src/components/nav-documents.tsx b/apps/react/src/components/nav-documents.tsx
deleted file mode 100644
index 972a543..0000000
--- a/apps/react/src/components/nav-documents.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-"use client";
-
-import { type Icon, IconDots, IconFolder, IconShare3, IconTrash } from "@tabler/icons-react";
-
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
-import {
- SidebarGroup,
- SidebarGroupLabel,
- SidebarMenu,
- SidebarMenuAction,
- SidebarMenuButton,
- SidebarMenuItem,
- useSidebar,
-} from "@/components/ui/sidebar";
-
-export function NavDocuments({
- items,
-}: {
- items: {
- name: string;
- url: string;
- icon: Icon;
- }[];
-}) {
- const { isMobile } = useSidebar();
-
- return (
-
- Documents
-
- {items.map((item) => (
-
-
-
-
- {item.name}
-
-
-
-
-
-
- More
-
-
-
-
-
- Open
-
-
-
- Share
-
-
-
-
- Delete
-
-
-
-
- ))}
-
-
-
- More
-
-
-
-
- );
-}
diff --git a/apps/react/src/components/nav-main.tsx b/apps/react/src/components/nav-main.tsx
deleted file mode 100644
index ac0332f..0000000
--- a/apps/react/src/components/nav-main.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-"use client";
-
-import { type Icon, IconCirclePlusFilled, IconMail } from "@tabler/icons-react";
-
-import { Button } from "@/components/ui/button";
-import {
- SidebarGroup,
- SidebarGroupContent,
- SidebarMenu,
- SidebarMenuButton,
- SidebarMenuItem,
-} from "@/components/ui/sidebar";
-
-export function NavMain({
- items,
-}: {
- items: {
- title: string;
- url: string;
- icon?: Icon;
- }[];
-}) {
- return (
-
-
-
-
-
-
- Quick Create
-
-
-
-
-
- {items.map((item) => (
-
-
- {item.icon && }
- {item.title}
-
-
- ))}
-
-
-
- );
-}
diff --git a/apps/react/src/components/nav-secondary.tsx b/apps/react/src/components/nav-secondary.tsx
deleted file mode 100644
index 7690c2d..0000000
--- a/apps/react/src/components/nav-secondary.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-"use client";
-
-import type { Icon } from "@tabler/icons-react";
-import type * as React from "react";
-
-import {
- SidebarGroup,
- SidebarGroupContent,
- SidebarMenu,
- SidebarMenuButton,
- SidebarMenuItem,
-} from "@/components/ui/sidebar";
-
-export function NavSecondary({
- items,
- ...props
-}: {
- items: {
- title: string;
- url: string;
- icon: Icon;
- }[];
-} & React.ComponentPropsWithoutRef) {
- return (
-
-
-
- {items.map((item) => (
-
-
-
-
- {item.title}
-
-
-
- ))}
-
-
-
- );
-}
diff --git a/apps/react/src/components/nav-user.controller.ts b/apps/react/src/components/nav-user.controller.ts
deleted file mode 100644
index 00667ce..0000000
--- a/apps/react/src/components/nav-user.controller.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Controller } from "../libraries/controller.tsx";
-import { type User as ZitadelUser, zitadel } from "../services/zitadel.ts";
-
-export class NavUserController extends Controller<{
- user: User;
-}> {
- async onInit() {
- return {
- user: await this.#getAuthenticatedUser(),
- };
- }
-
- async #getAuthenticatedUser(): Promise {
- const user = await zitadel.userManager.getUser();
- if (user === null) {
- throw new Error("Failed to resolve user session");
- }
- return getUserProfile(user);
- }
-
- signout() {
- zitadel.signout();
- }
-}
-
-function getUserProfile({ profile }: ZitadelUser): User {
- const user: User = { name: "Unknown", email: "unknown@acme.none", avatar: "" };
- if (profile.name) {
- user.name = profile.name;
- } else if (profile.given_name && profile.family_name) {
- user.name = `${profile.given_name} ${profile.family_name}`;
- } else if (profile.given_name) {
- user.name = profile.given_name;
- }
- if (profile.email) {
- user.email = profile.email;
- }
- if (profile.picture !== undefined) {
- user.avatar = profile.picture;
- }
- return user;
-}
-
-type User = {
- name: string;
- email: string;
- avatar: string;
-};
diff --git a/apps/react/src/components/nav-user.tsx b/apps/react/src/components/nav-user.tsx
deleted file mode 100644
index 0566929..0000000
--- a/apps/react/src/components/nav-user.tsx
+++ /dev/null
@@ -1,158 +0,0 @@
-"use client";
-
-import { IconCreditCard, IconDotsVertical, IconLogout, IconNotification, IconUserCircle } from "@tabler/icons-react";
-
-import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
-import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from "@/components/ui/sidebar";
-
-import { makeControllerComponent } from "../libraries/controller.tsx";
-import { NavUserController } from "./nav-user.controller.ts";
-
-export const NavUser = makeControllerComponent(NavUserController, ({ user, signout }) => {
- const { isMobile } = useSidebar();
- return (
-
-
-
-
-
-
-
- CN
-
-
- {user.name}
- {user.email}
-
-
-
-
-
-
-
-
-
- CN
-
-
- {user.name}
- {user.email}
-
-
-
-
-
-
-
- Account
-
-
-
- Billing
-
-
-
- Notifications
-
-
-
- signout()}>
-
- Log out
-
-
-
-
-
- );
-});
-
-/*
-export function NavUser() {
- const [{ user }, loading, { signout }] = useController(NavUserController);
- const { isMobile } = useSidebar();
- if (loading === true || user === undefined) {
- return null;
- }
- return (
-
-
-
-
-
-
-
- CN
-
-
- {user.name}
- {user.email}
-
-
-
-
-
-
-
-
-
- CN
-
-
- {user.name}
- {user.email}
-
-
-
-
-
-
-
- Account
-
-
-
- Billing
-
-
-
- Notifications
-
-
-
- signout()}>
-
- Log out
-
-
-
-
-
- );
-}
-*/
diff --git a/apps/react/src/components/site-header.tsx b/apps/react/src/components/site-header.tsx
deleted file mode 100644
index c21931f..0000000
--- a/apps/react/src/components/site-header.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Button } from "@/components/ui/button";
-import { Separator } from "@/components/ui/separator";
-import { SidebarTrigger } from "@/components/ui/sidebar";
-
-export function SiteHeader() {
- return (
-
- );
-}
diff --git a/apps/react/src/components/theme-provider.tsx b/apps/react/src/components/theme-provider.tsx
deleted file mode 100644
index 4d676bd..0000000
--- a/apps/react/src/components/theme-provider.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { createContext, useContext, useEffect, useState } from "react";
-
-type Theme = "dark" | "light" | "system";
-
-type ThemeProviderProps = {
- children: React.ReactNode;
- defaultTheme?: Theme;
- storageKey?: string;
-};
-
-type ThemeProviderState = {
- theme: Theme;
- setTheme: (theme: Theme) => void;
-};
-
-const initialState: ThemeProviderState = {
- theme: "system",
- setTheme: () => null,
-};
-
-const ThemeProviderContext = createContext(initialState);
-
-export function ThemeProvider({
- children,
- defaultTheme = "system",
- storageKey = "vite-ui-theme",
- ...props
-}: ThemeProviderProps) {
- const [theme, setTheme] = useState(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme);
-
- useEffect(() => {
- const root = window.document.documentElement;
-
- root.classList.remove("light", "dark");
-
- if (theme === "system") {
- const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
-
- root.classList.add(systemTheme);
- return;
- }
-
- root.classList.add(theme);
- }, [theme]);
-
- const value = {
- theme,
- setTheme: (theme: Theme) => {
- localStorage.setItem(storageKey, theme);
- setTheme(theme);
- },
- };
-
- return (
-
- {children}
-
- );
-}
-
-export const useTheme = () => {
- const context = useContext(ThemeProviderContext);
-
- if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider");
-
- return context;
-};
diff --git a/apps/react/src/components/ui/avatar.tsx b/apps/react/src/components/ui/avatar.tsx
deleted file mode 100644
index 35db151..0000000
--- a/apps/react/src/components/ui/avatar.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as AvatarPrimitive from "@radix-ui/react-avatar";
-import * as React from "react";
-
-import { cn } from "../../libraries/utils.ts";
-
-const Avatar = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-Avatar.displayName = AvatarPrimitive.Root.displayName;
-
-const AvatarImage = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AvatarImage.displayName = AvatarPrimitive.Image.displayName;
-
-const AvatarFallback = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
-
-export { Avatar, AvatarImage, AvatarFallback };
diff --git a/apps/react/src/components/ui/breadcrumb.tsx b/apps/react/src/components/ui/breadcrumb.tsx
deleted file mode 100644
index 126581a..0000000
--- a/apps/react/src/components/ui/breadcrumb.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { Slot } from "@radix-ui/react-slot";
-import { ChevronRight, MoreHorizontal } from "lucide-react";
-import * as React from "react";
-
-import { cn } from "@/libraries/utils";
-
-const Breadcrumb = React.forwardRef<
- HTMLElement,
- React.ComponentPropsWithoutRef<"nav"> & {
- separator?: React.ReactNode;
- }
->(({ ...props }, ref) => );
-Breadcrumb.displayName = "Breadcrumb";
-
-const BreadcrumbList = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbList.displayName = "BreadcrumbList";
-
-const BreadcrumbItem = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbItem.displayName = "BreadcrumbItem";
-
-const BreadcrumbLink = React.forwardRef<
- HTMLAnchorElement,
- React.ComponentPropsWithoutRef<"a"> & {
- asChild?: boolean;
- }
->(({ asChild, className, ...props }, ref) => {
- const Comp = asChild ? Slot : "a";
-
- return ;
-});
-BreadcrumbLink.displayName = "BreadcrumbLink";
-
-const BreadcrumbPage = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbPage.displayName = "BreadcrumbPage";
-
-const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<"li">) => (
- svg]:w-3.5 [&>svg]:h-3.5", className)} {...props}>
- {children ?? }
-
-);
-BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
-
-const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
-
-
- More
-
-);
-BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
-
-export {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
- BreadcrumbEllipsis,
-};
diff --git a/apps/react/src/components/ui/button.tsx b/apps/react/src/components/ui/button.tsx
deleted file mode 100644
index f4f67f1..0000000
--- a/apps/react/src/components/ui/button.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Slot } from "@radix-ui/react-slot";
-import { cva, type VariantProps } from "class-variance-authority";
-import * as React from "react";
-
-import { cn } from "../../libraries/utils.ts";
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
- {
- variants: {
- variant: {
- default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
- secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-9 px-4 py-2",
- sm: "h-8 rounded-md px-3 text-xs",
- lg: "h-10 rounded-md px-8",
- icon: "h-9 w-9",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- },
-);
-
-export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean;
-}
-
-const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button";
- return ;
- },
-);
-Button.displayName = "Button";
-
-export { Button, buttonVariants };
diff --git a/apps/react/src/components/ui/dropdown-menu.tsx b/apps/react/src/components/ui/dropdown-menu.tsx
deleted file mode 100644
index 696a682..0000000
--- a/apps/react/src/components/ui/dropdown-menu.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
-import { Check, ChevronRight, Circle } from "lucide-react";
-import * as React from "react";
-
-import { cn } from "../../libraries/utils.ts";
-
-const DropdownMenu = DropdownMenuPrimitive.Root;
-
-const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
-
-const DropdownMenuGroup = DropdownMenuPrimitive.Group;
-
-const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
-
-const DropdownMenuSub = DropdownMenuPrimitive.Sub;
-
-const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
-
-const DropdownMenuSubTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ className, inset, children, ...props }, ref) => (
-
- {children}
-
-
-));
-DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
-
-const DropdownMenuSubContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
-
-const DropdownMenuContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, sideOffset = 4, ...props }, ref) => (
-
-
-
-));
-DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
-
-const DropdownMenuItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ className, inset, ...props }, ref) => (
- svg]:size-4 [&>svg]:shrink-0",
- inset && "pl-8",
- className,
- )}
- {...props}
- />
-));
-DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
-
-const DropdownMenuCheckboxItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, checked, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-));
-DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
-
-const DropdownMenuRadioItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-));
-DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
-
-const DropdownMenuLabel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ className, inset, ...props }, ref) => (
-
-));
-DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
-
-const DropdownMenuSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
-
-const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => {
- return ;
-};
-DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
-
-export {
- DropdownMenu,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuCheckboxItem,
- DropdownMenuRadioItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuShortcut,
- DropdownMenuGroup,
- DropdownMenuPortal,
- DropdownMenuSub,
- DropdownMenuSubContent,
- DropdownMenuSubTrigger,
- DropdownMenuRadioGroup,
-};
diff --git a/apps/react/src/components/ui/field.tsx b/apps/react/src/components/ui/field.tsx
deleted file mode 100644
index 79d6600..0000000
--- a/apps/react/src/components/ui/field.tsx
+++ /dev/null
@@ -1,222 +0,0 @@
-import { cva, type VariantProps } from "class-variance-authority";
-import { useMemo } from "react";
-
-import { Label } from "@/components/ui/label";
-import { Separator } from "@/components/ui/separator";
-import { cn } from "@/libraries/utils";
-
-function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
- return (
-