diff --git a/components/mdx.tsx b/components/mdx.tsx index b6ff1ca..911b868 100644 --- a/components/mdx.tsx +++ b/components/mdx.tsx @@ -1,13 +1,19 @@ import defaultMdxComponents from 'fumadocs-ui/mdx'; +import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; import { Card, Cards } from 'fumadocs-ui/components/card'; +import { Step, Steps } from 'fumadocs-ui/components/steps'; import { Tabs, TabItem } from './mdx-tabs'; import type { MDXComponents } from 'mdx/types'; export function getMDXComponents(components?: MDXComponents) { return { ...defaultMdxComponents, + Accordion, + Accordions, Card, Cards, + Step, + Steps, Tabs, TabItem, ...components, diff --git a/content/docs/developer-docs/dashboarding/build-a-custom-dashboard-widget-provider.mdx b/content/docs/developer-docs/dashboarding/build-a-custom-dashboard-widget-provider.mdx index 325c3ee..fda3ed5 100644 --- a/content/docs/developer-docs/dashboarding/build-a-custom-dashboard-widget-provider.mdx +++ b/content/docs/developer-docs/dashboarding/build-a-custom-dashboard-widget-provider.mdx @@ -31,7 +31,7 @@ Use both decorators: The runtime registration path is: -- decorator metadata -> introspection (`SolidIntrospectService`) -> registry (`SolidRegistry`) -> runtime resolver (`DashboardRuntimeService`) +- Decorator metadata -> introspection (`SolidIntrospectService`) -> registry (`SolidRegistry`) -> runtime resolver (`DashboardRuntimeService`) ## Provider Template @@ -92,8 +92,8 @@ export class ExampleDashboardWidgetProvider implements IDashboardWidgetDataProvi The framework now includes a canonical reference implementation for a fully custom queue-focused widget: -- backend provider: `MqDashboardQueueSlaHeatmapProvider` -- frontend widget: `QueueSlaHeatmapWidget` +- Backend provider: `MqDashboardQueueSlaHeatmapProvider` +- Frontend widget: `QueueSlaHeatmapWidget` The provider output contract is intentionally explicit: @@ -126,9 +126,9 @@ The provider output contract is intentionally explicit: ``` This RI is useful because it shows the recommended split: -- the provider owns data access and runtime contract design, -- the frontend widget owns the final visual treatment, -- and metadata binds the two together. +- The provider owns data access and runtime contract design. +- The frontend widget owns the final visual treatment. +- Metadata binds the two together. ## Recommended Implementation Practices @@ -140,9 +140,17 @@ This RI is useful because it shows the recommended split: ## Quick Validation Path -1. Start service. -2. Call definition endpoint and verify widget exists. -3. Call widget data endpoint: + + + Start service. + + + Call the definition endpoint and verify the widget exists. + + + Call the widget data endpoint. + + ```bash curl -X POST "$BASE_URL/dashboard///widgets//data" \ @@ -151,4 +159,4 @@ curl -X POST "$BASE_URL/dashboard///widgets//data" -d '{"variables": {}}' ``` -4. Verify `meta.providerName` and `data` payload shape. +Then verify `meta.providerName` and the `data` payload shape. diff --git a/content/docs/developer-docs/dashboarding/dashboard-metadata-authoring-guide.mdx b/content/docs/developer-docs/dashboarding/dashboard-metadata-authoring-guide.mdx index e43d90d..a6b700f 100644 --- a/content/docs/developer-docs/dashboarding/dashboard-metadata-authoring-guide.mdx +++ b/content/docs/developer-docs/dashboarding/dashboard-metadata-authoring-guide.mdx @@ -9,11 +9,11 @@ Dashboard definitions are authored in module metadata under the root-level `dash The dashboard schema has a small set of core players: -- the dashboard definition describes the screen itself, -- variables describe the inputs a user can use to filter or parameterise the dashboard, -- widgets describe the individual building blocks on the page, -- provider bindings connect those widgets to backend data, -- and the default layout describes how the widgets should initially be arranged. +- The dashboard definition describes the screen itself. +- Variables describe the inputs a user can use to filter or parameterise the dashboard. +- Widgets describe the individual building blocks on the page. +- Provider bindings connect those widgets to backend data. +- The default layout describes how the widgets should initially be arranged. @@ -134,9 +134,9 @@ Each widget binds to a backend provider using `dataProvider`. `providerContext` is a metadata-authored input passed through to the provider at runtime. It is useful for keeping provider classes reusable. For example: -- a KPI provider can use `providerContext.metric` to decide which aggregate to compute, -- a chart provider can use `providerContext.bucket` to choose `hour` vs `day`, -- a table provider can use `providerContext.columns` and `providerContext.sort` to shape the output. +- A KPI provider can use `providerContext.metric` to decide which aggregate to compute. +- A chart provider can use `providerContext.bucket` to choose `hour` vs `day`. +- A table provider can use `providerContext.columns` and `providerContext.sort` to shape the output. For custom frontend rendering, add `componentName`. @@ -176,9 +176,9 @@ Dashboards should be exposed via metadata-driven menu/action pairs. Recommended pattern: -- action type `custom` -- action path matching dashboard route -- menu item referencing the action +- Action type `custom` +- Action path matching dashboard route +- Menu item referencing the action The action route should follow the canonical dashboard route pattern defined in [solidRoutes.tsx](/Users/harishpatel/Code/javascript/solid-core-ui/src/routes/solidRoutes.tsx), which is: @@ -216,15 +216,15 @@ The dashboard widget permission format is: Where: -- the first segment is always `dashboard` -- the second segment is the dashboard name -- the third segment is the widget matcher +- The first segment is always `dashboard` +- The second segment is the dashboard name +- The third segment is the widget matcher The widget matcher supports: -- exact widget names +- Exact widget names - `*` for all widgets in a dashboard -- regex-style patterns in the widget segment +- Regex-style patterns in the widget segment Examples from the queue-health reference implementation: @@ -252,26 +252,58 @@ The permission check is enforced on the backend first. When a user does **not** have permission for a widget: -1. the backend does **not** invoke that widget's data provider at all -2. the backend returns a normalized unauthorized widget envelope -3. the frontend still renders the widget card in the grid -4. the widget body shows a compact `Unauthorized` state + + + The backend does **not** invoke that widget's data provider at all. + + + The backend returns a normalized unauthorized widget envelope. + + + The frontend still renders the widget card in the grid. + + + The widget body shows a compact `Unauthorized` state. + + This behavior is intentional because it preserves layout consistency while keeping protected widget data entirely server-side. To make dashboard permissions effective in a real project: -1. declare the explicit permission strings in module metadata -2. attach those permissions to one or more roles -3. assign those roles to users + + + Declare the explicit permission strings in module metadata. + + + Attach those permissions to one or more roles. + + + Assign those roles to users. + + That flow is standard SolidX RBAC behavior and dashboards follow the same model. ## Authoring Checklist -1. Define dashboard in `dashboards[]`. -2. Define variables with clear names and labels. -3. Bind each widget to a valid backend `dataProvider`. -4. Define a complete `defaultLayout` for all widgets. -5. Add action/menu entries for discoverable navigation. -6. Add explicit dashboard widget permissions and bind them to the right roles. + + + Define the dashboard in `dashboards[]`. + + + Define variables with clear names and labels. + + + Bind each widget to a valid backend `dataProvider`. + + + Define a complete `defaultLayout` for all widgets. + + + Add action and menu entries for discoverable navigation. + + + Add explicit dashboard widget permissions and bind them to the right roles. + + diff --git a/content/docs/developer-docs/dashboarding/frontend-dashboard-widget-extension-contract.mdx b/content/docs/developer-docs/dashboarding/frontend-dashboard-widget-extension-contract.mdx index 8826c11..a0b3bfd 100644 --- a/content/docs/developer-docs/dashboarding/frontend-dashboard-widget-extension-contract.mdx +++ b/content/docs/developer-docs/dashboarding/frontend-dashboard-widget-extension-contract.mdx @@ -59,9 +59,17 @@ Registered in: At runtime, rendering follows this order: -1. If metadata provides explicit component override (`componentName`), resolve it. -2. Else derive default renderer from widget type/runtime payload. -3. If no renderer is found, use `DefaultDashboardUnknownWidget`. + + + If metadata provides explicit component override (`componentName`), resolve it. + + + Else derive the default renderer from widget type and runtime payload. + + + If no renderer is found, use `DefaultDashboardUnknownWidget`. + + This makes custom rendering **optional** while preserving consistent baseline behavior. diff --git a/content/docs/developer-docs/dashboarding/index.mdx b/content/docs/developer-docs/dashboarding/index.mdx index 83f6d1c..8e59ab5 100644 --- a/content/docs/developer-docs/dashboarding/index.mdx +++ b/content/docs/developer-docs/dashboarding/index.mdx @@ -2,43 +2,56 @@ title: Intro icon: "layout-dashboard" description: Build metadata-driven dashboards in SolidX using backend data providers, frontend widget extensions, and user-specific layouts. -summary: This section explains the complete SolidX dashboarding architecture, including metadata authoring, provider registration, runtime APIs, widget rendering contracts, Gridstack layout persistence, and practical templates for creating new widgets end to end. +summary: Covers dashboard metadata, backend widget providers, frontend widget registration, layout persistence, and implementation patterns for dashboard features. sidebar_position: 2.6 --- -SolidX dashboarding is a **metadata-driven framework capability** for building operational and analytical dashboard experiences without hard-coding each screen. +## Dashboard Overview -It is designed around four principles: +SolidX dashboarding is a metadata-driven system for building operational and analytical dashboards without hard-coding each screen. -- metadata-first dashboard definitions, -- backend provider-driven data resolution, -- frontend extension-driven widget rendering, -- and per-user layout personalization. +The dashboarding model is organized around four layers: -The queue health reference dashboard also includes a canonical custom widget example, `QueueSlaHeatmapWidget`, which demonstrates the intended model: -- backend data providers remain mandatory, -- custom frontend rendering stays optional, -- and explicit widget overrides are only introduced when the default framework widget set is not enough. +- Metadata-defined dashboard composition. +- Backend provider-driven data resolution. +- Frontend extension-driven widget rendering. +- Per-user layout personalization. + +The queue health reference dashboard also includes a representative custom widget example, `QueueSlaHeatmapWidget`, which shows the intended model: +- Backend data providers remain mandatory. +- Custom frontend rendering stays optional. +- Explicit widget overrides are only introduced when the default framework widget set is not enough. -Think of a SolidX dashboard as a composition of four layers: -- metadata defines the dashboard, variables, widgets, and default layout, -- backend providers resolve the actual widget data, -- frontend widgets decide how that data is rendered, -- and user layout persistence personalizes the arrangement without changing the dashboard definition itself. +SolidX dashboarding is composed of four layers: +- Metadata defines the dashboard, variables, widgets, and default layout. +- Backend providers resolve widget data at runtime. +- Frontend widgets determine the rendering contract. +- User layout persistence personalizes arrangement without mutating the dashboard definition itself. -## Sample Dashboard - -![Dashboard Architecture Placeholder](/img/dashboarding/dashboard-architecture-overview.png) +## Dashboard Capabilities + + + + Define dashboards, variables, widgets, layout items, and navigation metadata from the platform side. + + + Implement and register backend providers that resolve the runtime data required by each widget. + + + Understand the frontend rendering contract and when custom widget components are necessary. + + + Use the templates as implementation starting points for dashboard-related backend and frontend work. + + -## Pages +## Sample Dashboard -- [Metadata Schema](./dashboard-metadata-authoring-guide.mdx): how to define dashboards, variables, widgets, layouts, and navigation metadata. -- [Widget Data Provider](./build-a-custom-dashboard-widget-provider.mdx): how backend providers are implemented, registered, and bound to widgets. -- [Widget UI](./frontend-dashboard-widget-extension-contract.mdx): how default rendering works and how custom widget components are introduced when needed. +![Dashboard architecture overview](/img/dashboarding/dashboard-architecture-overview.png) diff --git a/content/docs/developer-docs/extending/backend-customization/background-jobs.md b/content/docs/developer-docs/extending/backend-customization/background-jobs.mdx similarity index 94% rename from content/docs/developer-docs/extending/backend-customization/background-jobs.md rename to content/docs/developer-docs/extending/backend-customization/background-jobs.mdx index 2270f28..7fbcc27 100644 --- a/content/docs/developer-docs/extending/backend-customization/background-jobs.md +++ b/content/docs/developer-docs/extending/backend-customization/background-jobs.mdx @@ -16,9 +16,20 @@ keywords: solidx_concerns: [backend.background_jobs, new_background_job, new_sms_provider, new_email_provider, new_whatsapp_provider, add_custom_service_method, add_scheduled_job] --- - Background jobs in SolidX let you offload non-blocking work from request/response flows. + + + SolidX generates the runtime plumbing for background jobs, but the queue contract and the broker-specific handlers still need to be modeled explicitly. + + - Publishers enqueue jobs without blocking the request path. + - Subscribers consume jobs asynchronously using the selected broker. + - Queue definitions, payload contracts, and provider wiring decide how the work is routed and processed. + + This page is the bridge between business logic that should happen later and the runtime infrastructure that processes it reliably. + + + Common use cases: - Notification delivery (email/SMS/WhatsApp) @@ -40,11 +51,23 @@ Job execution state is tracked in: Every background job setup usually contains: -1. Queue options file (broker type, queue name, etc.) -2. Publisher class -3. PublisherFactory-based publish call from service/subscriber hook -4. Subscriber class -5. Module provider wiring + + + Queue options file (broker type, queue name, etc.) + + + Publisher class + + + `PublisherFactory`-based publish call from service/subscriber hook + + + Subscriber class + + + Module provider wiring + + Typed payloads are recommended for safer publish/subscribe contracts. @@ -79,7 +102,6 @@ Typical edit sequence for new jobs: 2. Add broker-specific publisher/subscriber files under `background-jobs//`. 3. Register providers in the owning module. 4. Publish from service/subscriber-hook code via `PublisherFactory`. - ## 1) Queue Options + Payload Contract ```ts @@ -241,10 +263,8 @@ Example: Use `prefetch` to tune parallelism for your workload. - `prefetch` is a RabbitMQ concept and is not used by the Database broker implementation. - ## Database Broker Example (Reference) For lightweight setups without RabbitMQ, use database-backed queues. @@ -331,7 +351,6 @@ export class EmailQueueSubscriberDatabase extends DatabaseSubscriber { } } ``` - ## Naming Convention Use clear broker-specific class names: @@ -344,6 +363,7 @@ Register them as standard Nest providers in the relevant module. When publishing, pass the logical publisher name to `PublisherFactory`. The factory resolves `` (with backward compatibility fallback for RabbitMQ naming). + ## Subscriber Logging (Quick Note) Base subscriber classes provide a lazy logger via a protected accessor: diff --git a/content/docs/developer-docs/extending/backend-customization/computation-providers.mdx b/content/docs/developer-docs/extending/backend-customization/computation-providers.mdx index 9e52325..80d8a67 100644 --- a/content/docs/developer-docs/extending/backend-customization/computation-providers.mdx +++ b/content/docs/developer-docs/extending/backend-customization/computation-providers.mdx @@ -1,15 +1,12 @@ --- -title: Computed Fields +title: Computation Providers icon: "calculator" description: Learn how to extend the backend with custom computation providers. -summary: Explains SolidX computed fields powered by computation providers for automatic value derivation (e.g., totals, full names, age). Covers metadata configuration including `computedFieldTriggerConfig` for specifying triggers (before/after insert/update/remove operations), `computedFieldValueProvider` class implementation, `IEntityPreComputeFieldProvider` and `IEntityPostComputeFieldProvider` interfaces, provider registration, and examples like `PaymentCollectionItemAmountProvider` for calculating amounts based on related records. +summary: Covers computed-field providers, trigger configuration, provider interfaces, registration, and runtime value derivation in the SolidX backend. keywords: [backend, computation providers, customization] solidx_concerns: [backend.custom_computed_fields, add_computed_field_provider, create_model_with_fields, add_field_to_a_model] --- - -# Computation Providers - ## Overview In SolidX, a **computed field** is a field whose value is always derived from other data - never set manually. Common examples include `totalPrice` (summed from line items), `fullName` (concatenated from first and last name), or `amountPaid` (aggregated from child payment records). @@ -20,12 +17,14 @@ A **computation provider** is the TypeScript class that implements the derivatio - Think of a computed field as a spreadsheet formula applied to a database record. You define the formula once (in the provider), declare which events should re-evaluate it (in the trigger config), and the platform handles execution automatically. - - The computed field in metadata is the contract - it declares what to compute and when. - - The computation provider is the class that contains the logic - it receives the triggering entity and computes the new value. - - Before operations run synchronously in the same transaction and are ideal when the value depends only on the entity itself. - - After operations run asynchronously after the save and are ideal when the value depends on related records or requires cross-entity writes. - So the intuition is: declare what triggers recomputation and write the logic once - SolidX handles when and how it runs. + SolidX can derive field values at runtime, but the derivation logic must be explicitly modeled and registered. + + - The computed field metadata declares which field is derived and which events should trigger recomputation. + - The computation provider contains the runtime logic that produces or persists the derived value. + - Use before operations when the value depends only on the triggering entity inside the current transaction. + - Use after operations when the value depends on related records or requires additional writes after persistence. + + This page is the bridge between computed-field metadata and the backend logic that keeps derived values consistent at runtime. @@ -45,10 +44,11 @@ For `after-*` triggers, `modelName` can be any model - related or otherwise. ---- - ## Configuration + + + ### Step 1 - Define the field in metadata Add the field to your model's metadata with `"type": "computed"` and specify: @@ -59,9 +59,7 @@ Add the field to your model's metadata with `"type": "computed"` and specify: **Example scenario:** `paymentCollectionItemDetail` records represent individual payment transactions. When a detail is inserted or updated (i.e., a payment comes in), the parent `paymentCollectionItem` needs its aggregate totals recalculated - `amountPaid`, `amountPending`, `totalAmountToBePaid`, and `status`. Since this involves writing to a related parent entity, `after-*` operations are the right choice here.
- - Example: amountPaid computed field on paymentCollectionItemDetail - + Example: amountPaid computed field on paymentCollectionItemDetail ```json { @@ -92,8 +90,8 @@ Add the field to your model's metadata with `"type": "computed"` and specify: Computed field configurations are loaded from the database and cached in the Solid Registry at startup. Any changes require a server restart to take effect. - ---- + + ### Step 2 - Implement the provider @@ -102,9 +100,7 @@ Implement `IEntityPreComputeFieldProvider` for before operations, or `IEntityPos **In this example**, `PaymentCollectionItemAmountProvider` implements `IEntityPostComputeFieldProvider` because it needs to query all related detail records and write aggregated totals back to the parent - work that can only happen after the triggering detail has been saved.
- - Example: PaymentCollectionItemAmountProvider - + Example: PaymentCollectionItemAmountProvider ```ts import { Injectable } from '@nestjs/common'; @@ -191,7 +187,8 @@ export class PaymentCollectionItemAmountProvider
---- +
+ ### Step 3 - Register the provider @@ -204,6 +201,9 @@ Register the provider as a NestJS provider in the module it belongs to. }) ``` + + + --- ## Provider Interfaces diff --git a/content/docs/developer-docs/extending/backend-customization/crud-service.mdx b/content/docs/developer-docs/extending/backend-customization/crud-service.mdx index a8008f8..165c51f 100644 --- a/content/docs/developer-docs/extending/backend-customization/crud-service.mdx +++ b/content/docs/developer-docs/extending/backend-customization/crud-service.mdx @@ -1,13 +1,13 @@ --- title: CRUD Service icon: "database" -description: Learn how to create and customize CRUD services in your application. +description: Reference for creating and customizing CRUD services in SolidX. summary: Guide to creating and customizing CRUD services in SolidX applications for managing data layer operations, including methods for create, read, update, and delete functionality with business logic integration. keywords: [backend, services, CRUD, customization] solidx_concerns: [backend.service_changes, using_crud_service_method, add_custom_service_method] --- -# CRUD Service - Usage & Extension Guide +## Overview The **CRUD Service** is the backbone of data management in **SolidX**. It standardizes Create, Read, Update, and Delete operations for any model and adds niceties like permission checks, field-level validation/transformations, media handling, and soft-delete recovery. @@ -19,8 +19,6 @@ The generated service classes for SolidX models already extend the CRUD service. ---- - ## What You Get Out‑of‑the‑Box - **Public API** (available on any subclass): @@ -40,8 +38,6 @@ The generated service classes for SolidX models already extend the CRUD service. - **Soft delete** & **recovery** flows supported - **Permission checks** via `CrudHelperService` ---- - ## Extending the CRUD Service **What this shows:** How to define a model‑specific service (e.g., `PersonService`) that **inherits** all CRUD methods and optionally adds custom methods like `findByEmail`. You typically inject this service into a controller to expose REST endpoints. @@ -90,8 +86,6 @@ Any subclass automatically inherits all CRUD methods and can call `this.repo`, ` ---- - ## DTOs You’ll Use When Reading **What this shows:** The shape of pagination & filtering DTOs your **clients** pass to `find`/`findOne`. You can extend or narrow these DTOs in your own app, but the base service already understands them via `CrudHelperService`. @@ -127,8 +121,6 @@ status?: string; // publish | draft (when draft/publish workflow is enabled) ```
---- - ## Permissions & Context **Note:** The optional `context` parameter (internally called `solidRequestContext`) is an object with an `activeUser` property holding the `ActiveUserData` for the current user. It is generally auto‑populated by controllers from the request context to perform permission checks before CRUD operations. If you call service methods manually, `context` is optional and defaults to `{}`. @@ -170,12 +162,13 @@ export interface ActiveUserData { ``` ---- - -## CrudService API (with Examples ) +## CrudService API (with Examples) Below are **explained** examples for each method. Read the **explanation** first, then expand the **closeable** snippet. + + + ### 1) `create(createDto, files?, context?)` **What this shows:** How to create an entity, including optional media uploads (`files`). Field managers validate & transform values (e.g., hashing passwords, enforcing regex/length). @@ -237,8 +230,8 @@ await personService.update( await personService.delete(12 /*, context? */); ``` - ---- + + ### 4) `find(filterDto, context?)` @@ -284,8 +277,6 @@ console.log(result.records); // Entity[] with optional `_media` key added ``` ---- - ### 5) `findOne(id, query, context?)` **What this shows:** How to fetch one entity by ID with relations populated and media URLs resolved into the non-persistent `_media` key. @@ -318,8 +309,8 @@ const first = (entity as any)["_media"]["fileLocation"][0] as MediaWithFullUrl; console.log(first._full_url); // absolute URL to the file ``` - ---- + + ### 6) `insertMany(createDtos, filesArray?, context?)` @@ -355,8 +346,8 @@ console.log(saved.length); // 2 await personService.deleteMany([101, 102, 103]); ``` - ---- + + ### 8) `recover(id, context?)` @@ -385,8 +376,8 @@ const res = await personService.recoverMany([101, 102, 103]); console.log(res.recoveredIds); // [101, 102, 103] ``` - ---- + + ## Media Population Cheat‑Sheet @@ -453,8 +444,6 @@ console.log(media._full_url); ``` ---- - ## Filters & Grouping Tips **What this shows:** How `filters`, `groupBy`, and `showSoftDeleted` affect results. Your `CrudHelperService` defines the exact grammar for `filters` and grouping, so adjust the payload to match your implementation. @@ -491,8 +480,6 @@ console.log(response); ``` ---- - ## Best Practices - Prefer `find({ fields: [...] })` to limit selected columns on heavy entities. @@ -500,8 +487,6 @@ console.log(response); - When adding media fields to models, configure a `MediaStorageProvider` in metadata. - Keep custom logic (side effects, complex computed values) in **Computation Providers** preferably or **TypeORM Subscribers** if necessary. ---- - ## Summary By extending `CRUDService` you reuse a **tested, consistent**, and **metadata‑driven** CRUD foundation across your modules. diff --git a/content/docs/developer-docs/extending/backend-customization/custom-seeders.md b/content/docs/developer-docs/extending/backend-customization/custom-seeders.mdx similarity index 88% rename from content/docs/developer-docs/extending/backend-customization/custom-seeders.md rename to content/docs/developer-docs/extending/backend-customization/custom-seeders.mdx index 86a3696..45d2453 100644 --- a/content/docs/developer-docs/extending/backend-customization/custom-seeders.md +++ b/content/docs/developer-docs/extending/backend-customization/custom-seeders.mdx @@ -7,9 +7,6 @@ keywords: [backend, seeders, customization, database, seed data] solidx_concerns: [] --- - -# Custom Seeders - ## Overview Seeders in SolidX let you populate your database with initial or test data - things like default roles, lookup values, demo records, or any other data your application needs to function. @@ -27,10 +24,7 @@ Create a new service class that: - Has a `seed()` method containing your seeding logic
- - - Example: Country Seeder - + Example: Country Seeder ```ts import { Injectable, Logger } from '@nestjs/common'; @@ -106,9 +100,17 @@ The `--seeder` (`-s`) flag specifies the **class name** of the seeder to run. ## How It Works -1. **Discovery** - On application bootstrap, SolidX scans all providers for the `@SolidSeeder` decorator and registers them in the `SolidRegistry`. -2. **Lookup** - When you run the `seed` CLI command, it looks up the seeder by class name from the registry. -3. **Execution** - The seeder's `seed()` method is called. + + + **Discovery** - On application bootstrap, SolidX scans all providers for the `@SolidSeeder` decorator and registers them in the `SolidRegistry`. + + + **Lookup** - When you run the `seed` CLI command, it looks up the seeder by class name from the registry. + + + **Execution** - The seeder's `seed()` method is called. + + ## Summary diff --git a/content/docs/developer-docs/extending/backend-customization/dashboard-providers.md b/content/docs/developer-docs/extending/backend-customization/dashboard-providers.md deleted file mode 100644 index 74f5180..0000000 --- a/content/docs/developer-docs/extending/backend-customization/dashboard-providers.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Dashboard Providers -icon: "layout-dashboard" -description: Create custom dashboard providers to return the data for rendering dashboard widgets. -summary: Introduction to creating custom dashboard providers in SolidX for fetching and returning data with UI options for dashboard widget rendering. Implementation details are pending future documentation updates. -keywords: [backend, dashboard, providers, customization] -solidx_concerns: [create/update_dashboard_widget] ---- - -In this section, we will explore how to create custom dashboard providers to return the data for rendering dashboard widgets. Dashboard providers are responsible for fetching and returning the data and UI options that will be displayed in the dashboard. - -How to create a custom dashboard provider: - -# TODO -Implementation pending diff --git a/content/docs/developer-docs/extending/backend-customization/dashboard-providers.mdx b/content/docs/developer-docs/extending/backend-customization/dashboard-providers.mdx new file mode 100644 index 0000000..d7ff962 --- /dev/null +++ b/content/docs/developer-docs/extending/backend-customization/dashboard-providers.mdx @@ -0,0 +1,26 @@ +--- +title: Dashboard Providers +icon: "layout-dashboard" +description: Create custom dashboard providers to return the data for rendering dashboard widgets. +summary: Overview of dashboard providers in SolidX and where to look next when building custom dashboard widget data sources. +keywords: [backend, dashboard, providers, customization] +solidx_concerns: [create/update_dashboard_widget] +--- + +Dashboard providers are responsible for fetching and returning the data and UI options that power dashboard widgets. + + + This page is currently a short reference while the full implementation guide is being expanded. + + +Use these pages first: + +- [Dashboard Metadata Authoring Guide](/docs/developer-docs/dashboarding/dashboard-metadata-authoring-guide) +- [Build a Custom Dashboard Widget Provider](/docs/developer-docs/dashboarding/build-a-custom-dashboard-widget-provider) +- [Frontend Dashboard Widget Extension Contract](/docs/developer-docs/dashboarding/frontend-dashboard-widget-extension-contract) + +If you are extending dashboard behavior from the backend side, the key implementation concerns are: + +- Selecting the provider contract to implement +- Shaping the returned widget data consistently +- Keeping provider output aligned with the frontend widget expectations diff --git a/content/docs/developer-docs/extending/backend-customization/dynamic-selection-providers.mdx b/content/docs/developer-docs/extending/backend-customization/dynamic-selection-providers.mdx index f1cedb3..b186389 100644 --- a/content/docs/developer-docs/extending/backend-customization/dynamic-selection-providers.mdx +++ b/content/docs/developer-docs/extending/backend-customization/dynamic-selection-providers.mdx @@ -2,13 +2,12 @@ title: Dynamic Dropdowns icon: "list-filter" description: Learn how to create dynamic selection providers to customize the selection options in your application. -summary: Explains creating dynamic selection providers for runtime option fetching from databases or APIs, replacing static lists. Covers field metadata configuration with `selectionDynamicProvider` and `selectionDynamicProviderCtxt`, implementing `ISelectionProvider` interface with `values()` method, provider registration, context handling, multi-select support, and examples like `StockApiSelectionProvider` for live exchange data. Highlights built-in `ListOfValuesSelectionProvider` for database queries. +summary: Covers provider-backed runtime option resolution, field metadata wiring, `ISelectionProvider` implementation, provider context, and registration. keywords: [backend, dynamic selection, providers, customization] solidx_concerns: [backend.custom_dynamic_selection_providers, dynamic_selection_provider] --- - # Dynamic Selection Providers Dynamic selection providers let you **fetch options at runtime**, rather than relying on static lists. @@ -24,10 +23,7 @@ Here’s an example field configuration using a custom provider named `StockApiS The `selectionDynamicProviderCtxt` specifies which fields from the API response should be used as labels and values.
- - - Example Configuration - + Example Configuration ```json { @@ -56,28 +52,20 @@ The `selectionDynamicProviderCtxt` specifies which fields from the API response - SolidX ships with built-in providers for common use cases - see [Built-in Selection Providers](../reference/built-in-selection-providers) for details on **`ListOfValuesSelectionProvider`** and **`PseudoForeignKeySelectionProvider`**. -- Create a **custom provider** when the logic for fetching or filtering is more complex, or when data comes from an external source like an API. + - Create a **custom provider** when the logic for fetching or filtering is more complex, or when data comes from an external source like an API. - ---- - ## 2. Creating the Provider Your provider class must implement the `ISelectionProvider` interface. The most important method is `values()`, which fetches and returns the available options. - + The value() method is deprecated. It can simply throw a NotImplementedException and is kept only for backward compatibility. - - -
+
- - - Example: StockApiSelectionProvider - + Example: StockApiSelectionProvider ```ts import { Injectable, Logger } from "@nestjs/common"; @@ -152,8 +140,6 @@ export class StockApiSelectionProvider ```
---- - ## 3. Registering the Provider Since providers are standard NestJS providers, register them in the module where they should be available. @@ -167,17 +153,12 @@ Since providers are standard NestJS providers, register them in the module where }) ``` ---- - ## 4. Interfaces Below are the core interfaces used when implementing a dynamic selection provider.
- - - ISelectionProvider Interface - + ISelectionProvider Interface ```ts export interface ISelectionProvider { diff --git a/content/docs/developer-docs/extending/backend-customization/email-providers.mdx b/content/docs/developer-docs/extending/backend-customization/email-providers.mdx index 7265afc..3207679 100644 --- a/content/docs/developer-docs/extending/backend-customization/email-providers.mdx +++ b/content/docs/developer-docs/extending/backend-customization/email-providers.mdx @@ -2,14 +2,12 @@ title: Email Providers icon: "mail" description: Learn how to create and configure custom email providers in SolidX. -summary: Guide to creating custom email providers beyond the built-in SMTP provider. Covers implementing the `IMail` interface with `@MailProvider()` decorator, using `EmailTemplateService` for templates, `PublisherFactory` for background job queuing, methods for synchronous/asynchronous sending with and without templates, handling attachments, API-based service integration (e.g., third-party email APIs), and proper error handling for email delivery. +summary: Covers `IMail` implementation, provider registration, template-driven sending, background delivery, attachments, and external email-service integration. keywords: [backend, email providers, customization] solidx_concerns: [new_email_provider] --- -# 📧 Email Providers - -## 🧩 Overview +## Overview SolidX provides an `SMTP` email provider out of the box, which supports sending emails **both synchronously** and **asynchronously** (via background jobs). However, there may be cases where you need to create your own provider - for example, to send emails using a **third‑party API service**. @@ -18,20 +16,15 @@ To make this easy, SolidX offers abstractions that help you implement your own p -## ⚙️ Steps to Create a Custom Email Provider +## Steps to Create a Custom Email Provider ### 1. Implement a Custom Email Service Below is a sample implementation of a custom email provider using a hypothetical API‑based service. -It implements the `IMail` interface and is decorated with `@MailProvider()`. - -It uses `EmailTemplateService` for handling email templates and `PublisherFactory` for queuing emails. - -This class provies implementation for sending email with and without templates, both synchronously and asynchronously. - -All the custom email sending logic (e.g., API calls) should be placed in the `sendEmailSynchronously` method. Rest of the code handles queuing and template rendering, which can be reused across different providers. +It implements the `IMail` interface and is decorated with `@MailProvider()`. It uses `EmailTemplateService` for template handling and `PublisherFactory` for queued delivery. +This class supports sending email both with and without templates, synchronously or asynchronously. Put your custom email sending logic, such as API calls, in `sendEmailSynchronously()`. The rest of the class handles queueing and template rendering, which can be reused across providers. ```ts import { HttpService } from "@nestjs/axios"; import { Inject, Injectable, Logger } from "@nestjs/common"; @@ -163,7 +156,7 @@ export class AppModule {} You can now use `MailFactory` to send emails either **via templates** or **manually**. -#### ✅ Example: Using an Email Template +#### Example: Using an Email Template ```ts import { MailFactory } from "@solidxai/core"; @@ -186,7 +179,7 @@ await mailService.sendEmailUsingTemplate( ); ``` -#### ✉️ Example: Sending a Manual Email (Without Template) +#### Example: Sending a Manual Email (Without Template) ```ts import { MailFactory } from "@solidxai/core"; @@ -204,7 +197,7 @@ await mailService.sendEmail( -## 🧠 Interface Definition +## Interface Definition The `IMail` interface defines two main methods your provider must implement. @@ -248,13 +241,11 @@ Use email templates for better separation of content and logic. It allows you to -## ✅ Summary +## Summary | Step | Description | |------|--------------| -| 1️⃣ | Create a class implementing `IMail` | -| 2️⃣ | Decorate it with `@MailProvider()` | -| 3️⃣ | Register it in your module | -| 4️⃣ | Use `MailFactory` to send emails (template or manual) | - - +| 1 | Create a class implementing `IMail` | +| 2 | Decorate it with `@MailProvider()` | +| 3 | Register it in your module | +| 4 | Use `MailFactory` to send emails (template or manual) | diff --git a/content/docs/developer-docs/extending/backend-customization/extending-controllers.md b/content/docs/developer-docs/extending/backend-customization/extending-controllers.mdx similarity index 97% rename from content/docs/developer-docs/extending/backend-customization/extending-controllers.md rename to content/docs/developer-docs/extending/backend-customization/extending-controllers.mdx index e23ca87..7c5b957 100644 --- a/content/docs/developer-docs/extending/backend-customization/extending-controllers.md +++ b/content/docs/developer-docs/extending/backend-customization/extending-controllers.mdx @@ -6,15 +6,11 @@ summary: Covers extending NestJS controllers in SolidX to add custom endpoints o keywords: [backend, controllers, customization] solidx_concerns: [backend.controller_changes, add_controller_endpoint] --- - - -# Extending Controllers +## Extending Controllers In SolidX, **controllers** are responsible for handling incoming requests and returning responses. Customizing controllers allows you to **add new endpoints**, modify existing ones, or introduce business-specific logic into your application. ---- - ## Adding a New Endpoint To add a new endpoint to an existing controller: @@ -27,8 +23,6 @@ To add a new endpoint to an existing controller: You can also create an entirely new controller by adding a new file in the `controllers` directory and defining your custom logic there. ---- - ### Example: Extending `InstituteController`
@@ -76,8 +70,6 @@ export class CustomPayloadDto { The first method (`activateInstitute`) handles `POST /activate-institute-portal` requests, while the second (`performCustomLogicUsingBody`) demonstrates handling **multipart/form-data** (files + JSON). ---- - ## Permission Auto-Generation @@ -89,9 +81,7 @@ InstituteController.activateInstitute ``` ---- - -## Related Recipes (TODO) +## Related Topics - Creating a Custom Controller - Creating a Controller Endpoint with Custom Authentication diff --git a/content/docs/developer-docs/extending/backend-customization/extending-repositories.md b/content/docs/developer-docs/extending/backend-customization/extending-repositories.mdx similarity index 91% rename from content/docs/developer-docs/extending/backend-customization/extending-repositories.md rename to content/docs/developer-docs/extending/backend-customization/extending-repositories.mdx index 213331d..d2e903b 100644 --- a/content/docs/developer-docs/extending/backend-customization/extending-repositories.md +++ b/content/docs/developer-docs/extending/backend-customization/extending-repositories.mdx @@ -7,26 +7,22 @@ keywords: [backend, repositories, customization] solidx_concerns: [backend.repository_changes, extending_repository] --- -# Extending Repositories - ## Overview [Generated repositories](../code-generation#repository) inherit from `SolidBaseRepository`, which already: -- wraps TypeORM with metadata-aware behavior, -- enforces query-level access control via `SecurityRuleRepository`, -- provides contextual access with `RequestContextService`, and +- Wraps TypeORM with metadata-aware behavior, +- Enforces query-level access control via `SecurityRuleRepository`, +- Provides contextual access with `RequestContextService`, and - **overrides the default TypeORM `find` methods** (`find`, `findOne`, `findAndCount`, etc.) so they remain security-aware. **Why extend?** To keep *business-specific queries* out of services/controllers and in a single, testable, composable layer. Extending repositories lets you: -- write expressive methods using simple `find*` calls (since they are already overridden to respect security rules), -- centralize complex joins or custom query builder logic when needed, -- reuse the same queries across multiple services, and -- maintain a clean separation between *data access* and *business logic*. - ---- +- Write expressive methods using simple `find*` calls (since they are already overridden to respect security rules), +- Centralize complex joins or custom query builder logic when needed, +- Reuse the same queries across multiple services, and +- Maintain a clean separation between *data access* and *business logic*. ## Step-by-step: add a custom method @@ -77,8 +73,6 @@ export class FeeTypeRepository extends SolidBaseRepository { ```
---- - ### 2) Add a method using Query Builder For more complex cases (aggregations, raw joins, advanced conditions), fall back to `createQueryBuilder()`. @@ -102,8 +96,6 @@ async totalsByCategory(instituteId: number) { ```
---- - ### 3) Consume your custom repository methods
@@ -128,8 +120,6 @@ export class FeesService { ```
---- - ## Best practices - **Prefer `find` / `findOne` / `findAndCount`** when possible. They are overridden in `SolidBaseRepository` to remain security-aware and easier to read. @@ -138,8 +128,6 @@ export class FeesService { - **Return typed results** (entities for reads, raw objects for aggregates). - **Unit-test repository methods** to validate filtering, ordering, and joins. ---- - ## Quick reference
diff --git a/content/docs/developer-docs/extending/backend-customization/extending-services.mdx b/content/docs/developer-docs/extending/backend-customization/extending-services.mdx index 1eeecc8..3b0c3e9 100644 --- a/content/docs/developer-docs/extending/backend-customization/extending-services.mdx +++ b/content/docs/developer-docs/extending/backend-customization/extending-services.mdx @@ -2,14 +2,14 @@ title: Custom Services icon: "wrench" description: Learn how to extend backend services in SolidX. -summary: Explains extending NestJS services in SolidX to implement custom business logic beyond default CRUD operations. Covers creating service methods for domain-specific operations (e.g., activating portals, sending notifications), benefits of separation of concerns, reusability across controllers and scheduled jobs, improved testability, and consistency. Includes examples like `activateInstitutePortal()` with database updates and event publishing. +summary: Covers service-level backend customization for SolidX, including custom business operations, service design, and integration with controllers and jobs. keywords: [backend, services, customization] solidx_concerns: [backend.service_changes, add_custom_service_method, using_crud_service_method] --- import { KanbanSquare, Redo2, Beaker, CheckCheck } from 'lucide-react'; -# Extending Services +## Extending the Generated Service Layer In SolidX, **services** are responsible for implementing **business logic** and handling **data manipulation**. By extending services, you can introduce custom logic that goes beyond the default CRUD behavior provided by SolidX. diff --git a/content/docs/developer-docs/extending/backend-customization/extending-users.md b/content/docs/developer-docs/extending/backend-customization/extending-users.mdx similarity index 84% rename from content/docs/developer-docs/extending/backend-customization/extending-users.md rename to content/docs/developer-docs/extending/backend-customization/extending-users.mdx index 83bd8ba..b7a869c 100644 --- a/content/docs/developer-docs/extending/backend-customization/extending-users.md +++ b/content/docs/developer-docs/extending/backend-customization/extending-users.mdx @@ -17,21 +17,25 @@ This guide covers how to: - Add custom fields and relationships - Register an `ExtensionUserCreationProvider` to handle user creation automatically ---- - ## Configuring a Custom User Model As an example, consider extending the `User` model into an `InstituteUser` model. The `InstituteUser` includes fields such as `userType` and a relation to an `Institute`. ### Steps to Create a Custom User Model -1. Set `isChild: true` in your model metadata. -2. Specify `User` as the `parentModelUserKey`. -3. Add your custom fields and relationships. + + + Set `isChild: true` in your model metadata. + + + Specify `User` as the `parentModelUserKey`. + + + Add your custom fields and relationships. + +
- - Sample Field Metadata for instituteUser - + Sample Field Metadata for instituteUser ```json { @@ -73,16 +77,12 @@ As an example, consider extending the `User` model into an `InstituteUser` model This configuration generates list and form views in SolidX to manage your custom users. ---- - ## Generated Code for Custom User Models When `isChild: true` and `User` is the parent model, SolidX generates DTOs and an entity extending the base User model:
- - DTOs & Entity - + DTOs & Entity ```ts // Create DTO - extends CreateUserDto so all base user fields are available @@ -97,13 +97,11 @@ export class InstituteUser extends User { ... } ```
---- - ## Registering an Extension User Creation Provider User creation involves more than a simple insert - password hashing, role assignment, and email notifications all need to run correctly. -To handle this for your custom user, you need to register an **`ExtensionUserCreationProvider`**. This provider allows you to inject custom logic while creating a custom user +To handle this for your custom user, you need to register an **`ExtensionUserCreationProvider`**. This provider allows you to inject custom logic while creating a custom user. You will need to provide the custom logic to handle the additional fields and relationships of your custom user, while SolidX takes care of the standard user creation flow. @@ -209,8 +207,6 @@ export class FeesPortalModule {} That is all that is required. The generated `InstituteUserService` needs no `create()` override. ---- - ## Test Data Seeding Add `userType` (and any other extension fields) to your test user specs in `-metadata.json`. SolidX passes the full spec to `buildExtensionEntity` and `roles`, so any fields present in the JSON are available: @@ -238,15 +234,29 @@ No extra seeding code is needed - SolidX detects the extension fields and routes ## How It Works -1. At startup, SolidX discovers any class decorated with `@ExtensionUserCreationProvider()` and registers it in the `SolidRegistry`. -2. When `AuthenticationService.signUp()` is called (from the API endpoint, the seeder, or anywhere else), it inspects the incoming spec for fields beyond the base `SignUpDto` properties. -3. If extension fields are present, SolidX looks up the registered provider. If no provider is found, an `InternalServerErrorException` is thrown immediately. -4. `buildExtensionEntity(dto)` is called to obtain the correctly-typed extension entity with its custom columns populated. -5. `roles(dto)` is called to determine the roles to assign. -6. SolidX then runs the standard signup flow - password hashing, `activateUserOnRegistration` setting, role initialisation, and notifications - against the prepared entity using the provider's `repo`. -7. If no extension fields are present, `signUp` creates a plain `User` as before, and the provider is never consulted. - + + + At startup, SolidX discovers any class decorated with `@ExtensionUserCreationProvider()` and registers it in the `SolidRegistry`. + + + When `AuthenticationService.signUp()` is called, from the API endpoint, the seeder, or anywhere else, it inspects the incoming spec for fields beyond the base `SignUpDto` properties. + + + If extension fields are present, SolidX looks up the registered provider. If no provider is found, an `InternalServerErrorException` is thrown immediately. + + + `buildExtensionEntity(dto)` is called to obtain the correctly typed extension entity with its custom columns populated. + + + `roles(dto)` is called to determine the roles to assign. + + + SolidX then runs the standard signup flow - password hashing, `activateUserOnRegistration` setting, role initialisation, and notifications - against the prepared entity using the provider's `repo`. + + + If no extension fields are present, `signUp` creates a plain `User` as before, and the provider is never consulted. + + All user records, including custom ones, are stored in the same `ss_user` table. SolidX uses a discriminator column (`type`) to differentiate between custom user types. - diff --git a/content/docs/developer-docs/extending/backend-customization/index.mdx b/content/docs/developer-docs/extending/backend-customization/index.mdx index 8c8394c..821fa75 100644 --- a/content/docs/developer-docs/extending/backend-customization/index.mdx +++ b/content/docs/developer-docs/extending/backend-customization/index.mdx @@ -2,19 +2,43 @@ title: Backend icon: "server" description: This section provides an overview of backend customization capabilities in SolidX. -summary: This document provides an overview of backend customization capabilities in SolidX, covering how developers can extend the NestJS-based backend functionality. Topics include adding custom API endpoints to controllers, modifying and extending existing services with custom business logic, implementing custom providers for specialized functionality, and integrating additional backend features to meet specific application requirements beyond the default CRUD operations. +summary: Covers controller changes, service extensions, provider implementations, scheduled jobs, and other backend customization points beyond generated CRUD behavior. --- -# Overview -This section provides an overview of backend customization capabilities in SolidX. It covers how to extend the backend functionality, including adding custom endpoints, modifying existing services, adding custom providers, and more. +import { Blocks, DatabaseZap, Plug, ShieldCheck } from 'lucide-react'; +## Overview + +This section provides an overview of backend customization capabilities in SolidX. + +SolidX generates a large part of the backend foundation for you, but real applications still need project-specific backend work such as custom endpoints, service extensions, providers, security rules, integrations, and background processing. - SolidX generates a large amount of backend structure for you, but that does not mean the backend is closed for custom work. - The generated layer gives you a strong default foundation, while backend customization is where you introduce application-specific behavior. - - Use metadata when the requirement is declarative and platform-supported. - - Use backend customization when the requirement is business-specific or operationally unique. - - Think of this section as the bridge between generated CRUD and a real production backend. - So the intuition is: SolidX gives you the baseline backend quickly, and this section shows where to extend it safely. + SolidX generates a significant portion of the backend surface, but the runtime is intentionally open to supported customization. + + - The generated layer provides the default structural foundation. + - Use metadata where the requirement is declarative and already modeled by the platform. + - Use backend customization where the requirement is business-specific, integration-heavy, or operationally unique. + + This section is the bridge between generated CRUD infrastructure and a production backend with domain-specific behavior. + +## Backend Capabilities + +Use these backend extension areas when the generated CRUD baseline is not enough for the runtime behavior you need. + + + } title="Extend CRUD Safely"> + Add repository methods, service logic, and controller endpoints without breaking generated conventions. + + } title="Add Providers"> + Introduce email, SMS, WhatsApp, computed-field, dashboard, and dynamic-selection providers at the runtime extension points the platform expects. + + } title="Handle Background Work"> + Use scheduled jobs, background jobs, subscribers, and seeders for workflows that do not belong inside request handlers. + + } title="Control Access"> + Apply static or provider-backed security rules when record access depends on user identity, role composition, or business context. + + diff --git a/content/docs/developer-docs/extending/backend-customization/scheduled-jobs.mdx b/content/docs/developer-docs/extending/backend-customization/scheduled-jobs.mdx index afe7d62..477fe0d 100644 --- a/content/docs/developer-docs/extending/backend-customization/scheduled-jobs.mdx +++ b/content/docs/developer-docs/extending/backend-customization/scheduled-jobs.mdx @@ -1,16 +1,13 @@ --- title: Scheduled Jobs icon: "clock" -description: Learn how to write the scheduled jobs in your SolidX application. -summary: Explains creating scheduled jobs in SolidX for recurring tasks like notifications, cleanup, syncing, or maintenance. Covers implementing `IScheduledJob` interface with `@ScheduledJobProvider()` decorator, registering job services in modules, defining job metadata with schedule name, frequency, days of week, job class name, and module reference. Includes examples like `HelloWorldJobService` and late fee calculation jobs. +description: Learn how to create scheduled jobs in your SolidX application. +summary: Covers `IScheduledJob` implementation, job-provider registration, module wiring, and the metadata required to schedule recurring backend work. keywords: [backend, scheduled jobs, customization] solidx_concerns: [backend.scheduled_jobs, add_scheduled_job] --- - - - -# Creating Scheduled Jobs +## Creating Scheduled Jobs Scheduled jobs in SolidX allow you to run recurring tasks such as sending notifications, cleaning up records, syncing data, or performing regular maintenance. @@ -22,11 +19,7 @@ For the full metadata schema reference, see [Scheduled Jobs Metadata](/docs/deve -

- - -## Adding a New Scheduled Job -

+## Adding a New Scheduled Job Follow these steps to define and use a custom scheduled job: @@ -182,20 +175,32 @@ When the built-in frequencies aren't precise enough, set `frequency` to `"Custom - If the expression is invalid or missing, the platform logs an error and falls back to a 24-hour interval. - Use a tool like crontab.guru to build and validate your cron expressions before adding them to metadata. +Use a tool like [crontab.guru](https://crontab.guru) to build and validate your cron expressions before adding them to metadata. --- ## How It Works -The SolidX scheduler runs an internal polling loop every minute (powered by `@Cron(CronExpression.EVERY_MINUTE)` under the hood). On each tick it: - -1. **Fetches due jobs** - queries all active jobs where `nextRunAt ≤ now` or `nextRunAt` is null (newly created jobs that haven't run yet). -2. **Applies scheduling gates** - each job is checked against `startDate`/`endDate` (date range), `startTime`/`endTime` (time-of-day window), `dayOfWeek` (for Weekly), and `dayOfMonth` (for Monthly) before being allowed to execute. -3. **Guards against overlap** - if a job is still running from a previous tick it is skipped, preventing concurrent duplicate executions. -4. **Dispatches execution** - the job's `execute(job)` method is called with the full `ScheduledJob` entity, giving the handler access to all metadata. -5. **Updates tracking fields** - after a successful run, `lastRunAt` is stamped and `nextRunAt` is computed based on the configured frequency, so the scheduler knows exactly when to pick it up next. +The SolidX scheduler runs an internal polling loop every minute, powered by `@Cron(CronExpression.EVERY_MINUTE)` under the hood. On each tick it: + + + + **Fetches due jobs** - queries all active jobs where `nextRunAt ≤ now` or `nextRunAt` is null, for newly created jobs that have not run yet. + + + **Applies scheduling gates** - checks each job against `startDate`/`endDate` (date range), `startTime`/`endTime` (time-of-day window), `dayOfWeek` (for Weekly), and `dayOfMonth` (for Monthly) before allowing it to execute. + + + **Guards against overlap** - skips the job if it is still running from a previous tick, preventing concurrent duplicate executions. + + + **Dispatches execution** - calls the job's `execute(job)` method with the full `ScheduledJob` entity, giving the handler access to all metadata. + + + **Updates tracking fields** - stamps `lastRunAt` after a successful run and computes `nextRunAt` based on the configured frequency, so the scheduler knows exactly when to pick it up next. + + ### Environment Control diff --git a/content/docs/developer-docs/extending/backend-customization/security-rules.md b/content/docs/developer-docs/extending/backend-customization/security-rules.mdx similarity index 76% rename from content/docs/developer-docs/extending/backend-customization/security-rules.md rename to content/docs/developer-docs/extending/backend-customization/security-rules.mdx index 23da9c5..201de98 100644 --- a/content/docs/developer-docs/extending/backend-customization/security-rules.md +++ b/content/docs/developer-docs/extending/backend-customization/security-rules.mdx @@ -7,12 +7,10 @@ keywords: [backend, security, customization] solidx_concerns: [add/update_security_record_rule] --- - -# Security Rules in SolidX +## Overview Security rules control **who can see which records**. You attach rules **per role** and **per model** so different roles get different visibility. - By default, **no security rules are enforced**. If a model has no matching security rules for the active user's roles, SolidX does not add record-level restrictions for that model. @@ -25,14 +23,20 @@ By default, **no security rules are enforced**. If a model has no matching secur Security rules are especially useful when access logic depends on the active user, their role, or related records such as associations, territories, venues, or reporting structures. -## Two ways to define a rule +## Two Ways to Define a Rule SolidX supports two patterns: -1. **Static metadata filters** - Use `securityRuleConfig.filters` directly in metadata when the rule can be expressed as a normal SolidX filter object. -2. **Dynamic provider-backed filters** - Use `securityRuleConfigProvider` when the filter must be computed at runtime, for example by loading related records for the active user first. + + + **Static metadata filters** + Use `securityRuleConfig.filters` directly in metadata when the rule can be expressed as a normal SolidX filter object. + + + **Dynamic provider-backed filters** + Use `securityRuleConfigProvider` when the filter must be computed at runtime, for example by loading related records for the active user first. + + The provider-backed pattern is the right choice when access logic depends on data you cannot express cleanly in a static JSON snippet. @@ -61,11 +65,10 @@ Add entries to the `securityRules` array in your module metadata JSON. - Example: `model:lead-role:Surveyor`
- - Example: Institute Admin sees only their institute - + Institute Admin sees only their institute ```json + { "securityRules": [ { @@ -90,21 +93,19 @@ Add entries to the `securityRules` array in your module metadata JSON. This is enough when a direct filter is available and only simple active-user substitution is needed. -

- - Dynamic Security Rules With Custom Providers -

+## Dynamic Security Rules With Custom Providers Use a custom provider when the final filter must be built dynamically at runtime. Common examples: -- load the active user's associations first, then build an `$in` filter -- apply different filters for different roles inside one shared provider -- add model-specific logic inside the provider based on `securityRule.modelMetadata` -- return a deny-all fallback when required context cannot be resolved +- Load the active user's associations first, then build an `$in` filter +- Apply different filters for different roles inside one shared provider +- Add model-specific logic inside the provider based on `securityRule.modelMetadata` +- Return a deny-all fallback when required context cannot be resolved -In the core implementation, SolidX checks `securityRuleConfigProvider` first. If it is present, SolidX resolves that provider from the registry and calls its `securityRuleConfig(activeUser, securityRule)` method. If no provider is configured, SolidX falls back to parsing `securityRuleConfig` from metadata. +In the core implementation, SolidX checks `securityRuleConfigProvider` first. +If it is present, SolidX resolves that provider from the registry and calls its `securityRuleConfig(activeUser, securityRule)` method. If no provider is configured, SolidX falls back to parsing `securityRuleConfig` from metadata. ## Implement a custom security rule provider @@ -112,9 +113,9 @@ Create a provider class in your backend module and decorate it with `@SecurityRu The provider must: -- be decorated with `@Injectable()` -- implement `ISecurityRuleConfigProvider` -- return a `SecurityRuleConfig` +- Be decorated with `@Injectable()` +- Implement `ISecurityRuleConfigProvider` +- Return a `SecurityRuleConfig` Example pattern: @@ -194,7 +195,7 @@ This means the same provider can branch on: - `securityRule.role.name` - `securityRule.modelMetadata.singularName` -- any related application data you load yourself +- Any related application data you load yourself ## Register the provider in your module @@ -234,48 +235,55 @@ In metadata, point the rule at the provider by class name. This pattern is used in consuming projects where many role-and-model combinations reuse one dynamic provider, and the provider decides the exact filter to return for each rule. -## How rule evaluation works - -

- - How It Works -

+## How Rule Evaluation Works At query time: -1. `SolidBaseRepository` asks the security rule repository for rules matching the current model and the active user's roles. -2. For each matching rule: - - if `securityRuleConfigProvider` is set, SolidX calls the provider - - otherwise SolidX parses `securityRuleConfig` and resolves `$activeUserId` -3. Each evaluated rule contributes one filter group. -4. SolidX combines those rule groups with **OR** at the top level. -5. Within an individual rule's `filters`, your normal filter logic still applies, including `$and`, `$or`, relation traversal, `$in`, and so on. + + + `SolidBaseRepository` asks the security rule repository for rules matching the current model and the active user's roles. + + + For each matching rule, SolidX either calls the configured provider or parses `securityRuleConfig` and resolves `$activeUserId`. + + + Each evaluated rule contributes one filter group. + + + SolidX combines those rule groups with **OR** at the top level. + + + Within an individual rule's `filters`, your normal filter logic still applies, including `$and`, `$or`, relation traversal, `$in`, and so on. + + This is why users with multiple applicable roles effectively get the **most permissive** access across those matching rules. -### Mental model for combining rules + - **Across rules**: OR - **Inside one rule**: whatever your `filters` object says + + So if a user has: -- one rule that allows records from `venue A` -- another rule that allows records assigned to them personally +- One rule that allows records from `venue A` +- Another rule that allows records assigned to them personally -the final query can return records matching **either** rule. +The final query can return records matching **either** rule. ## Real-world pattern from a consuming project One common production pattern is: -- metadata creates one security rule per role and per model -- most of those rules point to the same `securityRuleConfigProvider` -- the provider loads user associations first -- the provider returns model-specific filters such as: - - leads in the user's venues - - call logs whose related lead is in the user's venues - - tighter status filters for roles like Telecaller +- Metadata creates one security rule per role and per model +- Most of those rules point to the same `securityRuleConfigProvider` +- The provider loads user associations first +- The provider returns model-specific filters such as: + - Leads in the user's venues + - Call logs whose related lead is in the user's venues + - Tighter status filters for roles like Telecaller This keeps metadata declarative while moving the dynamic logic into normal TypeScript service code. @@ -287,10 +295,7 @@ This keeps metadata declarative while moving the dynamic logic into normal TypeS As a rule of thumb: if you are tempted to encode business logic into awkward metadata or duplicate many near-identical rules, move that logic into a provider. -

- - Common Pitfalls & Troubleshooting -

+## Common Pitfalls & Troubleshooting - **Restart required:** Rules are loaded into the registry at startup. Restart the server after changing metadata or adding a new provider. - **Provider name must match:** `securityRuleConfigProvider` must match the registered provider name that SolidX resolves from the registry. @@ -312,6 +317,6 @@ DEFAULT_DATABASE_LOGGING=true ``` - Add temporary logging inside the provider to confirm: - - which rule was resolved - - which role and model were passed in - - what final filter object was returned + - Which rule was resolved + - Which role and model were passed in + - What final filter object was returned diff --git a/content/docs/developer-docs/extending/backend-customization/sms-providers.mdx b/content/docs/developer-docs/extending/backend-customization/sms-providers.mdx index 247da87..9891b0c 100644 --- a/content/docs/developer-docs/extending/backend-customization/sms-providers.mdx +++ b/content/docs/developer-docs/extending/backend-customization/sms-providers.mdx @@ -2,13 +2,12 @@ title: SMS Providers icon: "smartphone" description: Learn how to create and configure custom SMS providers in SolidX. -summary: Overview of the built-in SMS providers shipped with SolidX (Twilio, Msg91 transactional, Msg91 OTP) and how to implement a custom SMS provider using the ISMS interface. +summary: Covers the built-in SMS providers shipped with SolidX and the implementation model for custom providers using the `ISMS` interface. keywords: [backend, sms providers, customization] solidx_concerns: [new_sms_provider] --- - ## Overview SolidX ships with three built-in SMS providers: **TwilioSMSService**, **Msg91SMSService**, and **Msg91OTPService**. All support both **synchronous** sending and **asynchronous** (queued/background) delivery. @@ -23,7 +22,7 @@ While you can store SMS templates in SolidX, most providers (including Msg91) re --- -## 📦 Default SMS Providers +## Default SMS Providers SolidX includes three providers out of the box. Each is decorated with `@SmsProvider()`, which registers it for auto-discovery by `SmsServiceFactory`. @@ -40,8 +39,8 @@ SolidX includes three providers out of the box. Each is decorated with `@SmsProv Sends SMS via the [Twilio](https://www.twilio.com/) SDK. It is the only built-in provider that supports **plain text messages** via `sendSMS()` in addition to template-based messages. **Supports:** -- `sendSMS()` - sends a raw text body directly -- `sendSMSUsingTemplate()` - renders a Handlebars template and sends the result +- `sendSMS()` - Sends a raw text body directly +- `sendSMSUsingTemplate()` - Renders a Handlebars template and sends the result - Comma-separated recipients in the `to` field - Synchronous and queued async delivery @@ -82,7 +81,7 @@ export class NotificationService { Sends transactional SMS via [Msg91's](https://msg91.com/) `/flow` API endpoint. - + `sendSMS()` is **not supported** - calling it throws an error. You must use `sendSMSUsingTemplate()` with a template that has a `smsProviderTemplateId` matching a pre-approved Msg91 template. @@ -130,7 +129,7 @@ The template named `"order-confirmation"` must exist in SolidX and its `smsProvi Sends OTP SMS via [Msg91's](https://msg91.com/) dedicated `/otp` endpoint. Intended for one-time password delivery flows. - + `sendSMS()` is **not supported** - calling it throws an error. You must use `sendSMSUsingTemplate()` with a template that includes an `otp` parameter and a valid `smsProviderTemplateId`. @@ -170,7 +169,7 @@ export class AuthService { --- -## ⚙️ Steps to Create a Custom SMS Provider +## Steps to Create a Custom SMS Provider ### 1) Implement a Custom SMS Service @@ -277,7 +276,7 @@ export class CustomSMSService implements ISMS { } async sendSMSSynchronously(message: QueueMessage): Promise { - // 🧩 TODO: Add your custom SMS provider integration here. + // Add your custom SMS provider integration here. // e.g., call Twilio/Nexmo/your in‑house gateway API. this.logger.log( `Sending SMS synchronously to ${message.payload.to} using custom provider...` @@ -354,7 +353,7 @@ export class SomeService { --- -## 🧠 Interface Definition +## Interface Definition Your custom service must implement the `ISMS` interface: @@ -377,13 +376,13 @@ export interface ISMS { --- -## ✅ Summary +## Summary | Step | What you do | |---|---| -| 1️⃣ | Implement `CustomSMSService` (implements `ISMS`, decorated with `@SmsProvider()`) | -| 2️⃣ | Register it in your module | -| 3️⃣ | Use `SmsServiceFactory` to send template-based SMS | +| 1 | Implement `CustomSMSService` (implements `ISMS`, decorated with `@SmsProvider()`) | +| 2 | Register it in your module | +| 3 | Use `SmsServiceFactory` to send template-based SMS | diff --git a/content/docs/developer-docs/extending/backend-customization/solid-registry.md b/content/docs/developer-docs/extending/backend-customization/solid-registry.mdx similarity index 81% rename from content/docs/developer-docs/extending/backend-customization/solid-registry.md rename to content/docs/developer-docs/extending/backend-customization/solid-registry.mdx index 9612008..d773f10 100644 --- a/content/docs/developer-docs/extending/backend-customization/solid-registry.md +++ b/content/docs/developer-docs/extending/backend-customization/solid-registry.mdx @@ -7,128 +7,88 @@ keywords: [backend, solid registry, customization, metadata] --- -# Solid Registry Overview +## Overview -The **Solid Registry** is the central **discovery and configuration hub** of your SolidX application. +The **Solid Registry** is the central **discovery and configuration hub** of your SolidX application. It acts both as a **cache** and a **metadata manager**, providing: - **Fast lookups**: Components can be resolved without repeated database queries. - **Consistency**: Application-wide rules, modules, and providers are available in one place. - **Extensibility**: Drop in a new provider, decorate it, and the registry auto-discovers it. -At application startup, the registry loads all relevant components and makes them available for runtime resolution. +At application startup, the registry loads all relevant components and makes them available for runtime resolution. If you update registered metadata, you **must restart the application** to reload the registry. + -## Registered Components +Think of the Solid Registry as the runtime lookup layer for decorated backend extensions and loaded metadata. -The following components are tracked by the Solid Registry: +- Providers, rules, jobs, and similar runtime components are discovered at startup. +- The registry keeps those components available for fast runtime resolution. +- Metadata and provider changes do not become available until the application reloads them. + + +## Registered Components + +The following components are tracked by the Solid Registry: -

- - Seeders -

+### Seeders **Purpose:** Populate your database with initial or default data (e.g., system roles, default fee types). **How it works:** The registry maintains a catalog of all available seeders. Developers can easily list, execute, or selectively run seeders. **See also:** [Metadata Schema Overview](../../metadata_schema) - - -

- - Scheduled Jobs -

+### Scheduled Jobs **Purpose:** Define recurring tasks such as reminders, report generation, and cleanup jobs. **How it works:** Registered jobs are tied into the scheduling engine. The registry ensures all jobs are loaded, discoverable, and can be managed or paused centrally. **See also:** [Jobs & Scheduling](./scheduled-jobs) - - -

- - Selection Providers -

+### Selection Providers **Purpose:** Provide dynamic values for selection fields in the UI (e.g., dropdowns, filters). **How it works:** A `@SelectionProvider` class can be created, registered, and then consumed by form components. The registry ensures all providers are globally available without additional wiring. **See also:** [Field Metadata](../../metadata_schema/field-metadata) - - -

- - Computed Fields -

+### Computed Fields **Purpose:** Derive field values dynamically based on logic (e.g., total amount, status based on conditions). **How it works:** Each computed field provider is registered with metadata, making them discoverable by the runtime when evaluating entity fields. **See also:** [Computed Fields](/docs/developer-docs/extending/backend-customization/computation-providers) - - -

- - Solid Database Modules -

+### Solid Database Modules **Purpose:** Define your application’s database schema, models, and relations. **How it works:** Modules (like Fees, School, Library) are registered in the Solid Registry, ensuring schema consistency and discoverability across the application. **See also:** [Modules Overview](/docs/admin-docs/module-builder/module-management) - - -

- - Controllers -

+### Controllers **Purpose:** Handle incoming HTTP requests and expose routes. **How it works:** The registry tracks all controllers, enabling automated route mapping and simplifying metadata introspection for APIs. **See also:** [Controllers](./extending-controllers) - - -

- - Security Rules -

+### Security Rules **Purpose:** Restrict access to entities and fields based on roles and policies. **How it works:** The registry stores all declared rules. Every query automatically applies these rules by resolving them from the registry. **See also:** [Security Rules](./security-rules) - - -

- - Locales -

+### Locales **Purpose:** Manage localization, translations, and regional formats. **How it works:** Each locale configuration is registered at startup. Applications can dynamically switch or apply formats based on user preference. **See also:** [Localization](/docs/developer-docs/extending/backend-customization/solid-registry) - - -

- - Dashboard Variable Selection Providers -

+### Dashboard Variable Selection Providers **Purpose:** Provide dynamic lists of variables for dashboards (e.g., filters like branch, department, or timeframe). **How it works:** Developers can implement new providers that populate variables at runtime. The registry ensures these providers are available to all dashboards. **See also:** [Dashboards](./dashboard-providers) - - -

- - Dashboard Question Data Providers -

+### Dashboard Question Data Providers **Purpose:** Supply data sources for dashboard questions (charts, KPIs, summaries). **How it works:** Providers can query APIs, databases, or aggregates. The registry makes them available for dynamic dashboard rendering. @@ -138,14 +98,14 @@ The following components are tracked by the Solid Registry: ## When Is the Registry Populated? -All components are registered **at application startup**. +All components are registered **at application startup**. - This ensures they are immediately discoverable. - If you modify any registered metadata, restart the application. - Hot-reload of providers is not supported (yet). -'> **Note** + -''> If you are running the application in a dev mode i.e using `npm run solidx:dev`, the application will automatically restart when it detects file changes, so you don't need to manually restart it for registry changes to take effect. -' +If you are running the application in dev mode, for example with `npm run solidx:dev`, the application restarts automatically when it detects file changes. In that case, you usually do not need to restart it manually for registry changes to take effect. + diff --git a/content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.md b/content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.mdx similarity index 94% rename from content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.md rename to content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.mdx index 4d2d4f5..946c5e8 100644 --- a/content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.md +++ b/content/docs/developer-docs/extending/backend-customization/typeorm-subscribers.mdx @@ -17,9 +17,17 @@ Do **not** execute heavy business side effects directly inside `afterInsert`, `a Preferred flow: -1. TypeORM subscriber hook runs (`afterInsert`, `afterUpdate`, ...) -2. Hook publishes a queue message through `PublisherFactory` -3. Queue subscriber processes the actual business logic asynchronously + + + TypeORM subscriber hook runs (`afterInsert`, `afterUpdate`, ...). + + + The hook publishes a queue message through `PublisherFactory`. + + + A queue subscriber processes the actual business logic asynchronously. + + This publisher-subscriber pair should be your default pattern for subscriber-driven side effects. @@ -197,11 +205,13 @@ export class UserChangedJobSubscriber extends RabbitMqSubscriber - You can still use TypeORM hooks for lightweight in-memory data preparation, but not heavy side effects. - If in doubt, publish and process asynchronously. +
+ ## See Also - [Background Jobs](./background-jobs.md) diff --git a/content/docs/developer-docs/extending/backend-customization/whatsapp-providers.md b/content/docs/developer-docs/extending/backend-customization/whatsapp-providers.mdx similarity index 75% rename from content/docs/developer-docs/extending/backend-customization/whatsapp-providers.md rename to content/docs/developer-docs/extending/backend-customization/whatsapp-providers.mdx index 72b6ecb..060ff1b 100644 --- a/content/docs/developer-docs/extending/backend-customization/whatsapp-providers.md +++ b/content/docs/developer-docs/extending/backend-customization/whatsapp-providers.mdx @@ -7,9 +7,7 @@ keywords: [backend, whatsapp providers, customization] solidx_concerns: [new_whatsapp_provider] --- -# 📧 WhatsApp Providers - -## 🧩 Overview +## Overview SolidX provides a `Msg91` WhatsApp provider out of the box, which supports sending WhatsApp messages **both synchronously** and **asynchronously** (via background jobs). @@ -17,25 +15,24 @@ However, there may be cases where you need to create your own provider - for exa To make this easy, SolidX offers abstractions that help you implement your own provider while keeping the code **clean, testable, and decoupled**. -'> **Note** + + +For WhatsApp messages, there is no need to keep separate template management in SolidX, since most WhatsApp providers, such as Twilio and Msg91, have their own template management system. + +So SolidX allows you to send WhatsApp messages using the `templateId` and `parameters` configured in your WhatsApp provider platform. Here, `templateId` is the external template ID from your WhatsApp provider platform. -''> For whatsapp messages, there is no need to keep a separate template management in SolidX, since most whatsapp providers (e.g., Twilio, Msg91, etc) have their own template management system. -''> -''> So SolidX allows you to send whatsapp messages using the `templateId` and `parameters` as configured in your whatsapp provider platform. Here the templateId is the external templateId from your whatsapp provider platform. -' + -## ⚙️ Steps to Create a Custom WhatsApp Provider +## Steps to Create a Custom WhatsApp Provider ### 1. Implement a Custom WhatsApp Service Below is a sample implementation of a custom WhatsApp provider using a hypothetical API‑based service. -It implements the `IWhatsAppTransport` interface and is decorated with `@WhatsAppProvider()`. +It implements the `IWhatsAppTransport` interface and is decorated with `@WhatsAppProvider()`. The interface currently supports a single method, `sendWhatsAppMessage`, which takes the `to` phone number, `templateId`, and `parameters`. -The IWhatsAppTransport interface currently supports only 1 method `sendWhatsAppMessage` which takes the `to` phone number, `templateId` and `parameters` as input. - -Below is a sample implementation of a custom WhatsApp provider using a hypothetical API‑based service, which sends all messages asynchronously (queued). In case you want to send some messages synchronously, you can modify the logic in `sendWhatsAppMessage` and call the sendWhatsAppMessageSynchronously directly instead of queuing it. +This example sends all messages asynchronously. If you need synchronous delivery for some messages, update `sendWhatsAppMessage` to call `sendWhatsAppMessageSynchronously()` directly instead of queueing it. ```ts import { HttpService } from '@nestjs/axios'; @@ -110,11 +107,11 @@ export class AppModule {} -### 3. Use the `WhatsAppFactory` to Send WhatsApp Messages +### 3. Use the `WhatsAppFactory` to Send WhatsApp Messages You can now use `WhatsAppFactory` to send WhatsApp messages either **via templates** or **manually**. -#### ✅ Example: Sending a WhatsApp Message +#### Example: Sending a WhatsApp Message ```ts import { WhatsAppFactory } from "@solidxai/core"; @@ -129,7 +126,7 @@ await whatsappService.sendWhatsAppMessage( ); ``` -## 🧠 Interface Definition +## Interface Definition The `IWhatsAppTransport` interface defines the contract for sending WhatsApp messages. @@ -146,12 +143,11 @@ export interface IWhatsAppTransport { ``` -## ✅ Summary +## Summary | Step | Description | |------|--------------| - | 1️⃣ | Implement your custom WhatsApp provider by implementing the `IWhatsAppTransport` interface | - | 2️⃣ | Decorate it with `@WhatsAppProvider()` | - | 3️⃣ | Register it in your module | - | 4️⃣ | Use `WhatsAppFactory` to send WhatsApp messages | - +| 1 | Implement your custom WhatsApp provider by implementing the `IWhatsAppTransport` interface | +| 2 | Decorate it with `@WhatsAppProvider()` | +| 3 | Register it in your module | +| 4 | Use `WhatsAppFactory` to send WhatsApp messages | diff --git a/content/docs/developer-docs/extending/code-generation/index.mdx b/content/docs/developer-docs/extending/code-generation/index.mdx index 0a82373..f429d2f 100644 --- a/content/docs/developer-docs/extending/code-generation/index.mdx +++ b/content/docs/developer-docs/extending/code-generation/index.mdx @@ -1,45 +1,53 @@ --- title: Code Generation icon: "code" -description: Understand generated backend code in SolidX, how the CLI updates it, and the frontend conventions followed by solid-ui modules. -summary: This page explains how SolidX code generation works across the project. It covers the generated structure in `solid-api`, how CLI commands such as `refresh-model` update generated backend code from metadata, and the conventions used in `solid-ui` for registering project-specific modules, routes, reducers, middleware, extension components, and custom pages. It is intended as the single reference page for generated structure and related conventions. +description: Understand generated backend code in SolidX, how the CLI updates it, and the frontend conventions followed by `solid-ui` modules. +summary: Covers generated backend structure in `solid-api`, CLI regeneration flows, and the conventions used by `solid-ui` modules for routes, reducers, middleware, and extensions. --- -import { Box, Database, ToggleLeft, Terminal } from 'lucide-react'; +import { ToggleLeft, Terminal } from 'lucide-react'; -# Code Generation +## Generated Backend and Frontend Conventions SolidX uses metadata to generate and maintain large parts of the backend application in `solid-api`. -The frontend in `solid-ui` is different: it is **not** scaffolded model-by-model in the same way, but it does follow a clear set of conventions so project-specific UI modules can be discovered and registered dynamically. +The frontend in `solid-ui` is different. It is **not** scaffolded model-by-model in the same way, but it does follow a clear set of conventions so project-specific UI modules can be discovered and registered dynamically. -This page gives you the complete picture in one place: +This page explains what SolidX generates in `solid-api`, how the CLI keeps generated backend code aligned with metadata, and how `solid-ui` should be structured so it plugs cleanly into `@solidxai/core-ui`. -- what gets generated in `solid-api`, -- how the CLI updates generated backend code, -- and how `solid-ui` should be structured so it plugs cleanly into `@solidxai/core-ui`. + + +The backend is metadata-owned scaffolding that SolidX can regenerate safely. The frontend is convention-driven and expects module-owned structure so routes, widgets, reducers, and extension code can be discovered consistently. + + ## What Is Generated vs What Is Conventional? - - } title="solid-api (Generated)"> - Metadata drives the creation and maintenance of: - - NestJS module wiring - - Controllers - - Services - - DTOs - - Entities - - Repositories - - Model-related layout metadata - - } title="solid-ui (Convention-driven)"> - Projects follow a convention-based structure: - - App bootstrap lives in `src/` - - Feature folders define project-specific UI modules - - `*.ui-module.ts` files are discovered dynamically - - Each UI module contributes routes, Redux pieces, extension functions, and extension components - - + + + + Metadata drives the creation and maintenance of: + + - NestJS module wiring + - Controllers + - Services + - DTOs + - Entities + - Repositories + - Model-related layout metadata + + + + + Projects follow a convention-based structure: + + - App bootstrap lives in `src/` + - Feature folders define project-specific UI modules + - `*.ui-module.ts` files are discovered dynamically + - Each UI module contributes routes, Redux pieces, extension functions, and extension components + + + ## solid-api Generated Structure @@ -79,77 +87,85 @@ solid-api/ │ └── fee-type.service.ts ``` -### Controller + + -Generated controllers expose the REST API surface for the model. They typically include: + Generated controllers expose the REST API surface for the model. They typically include: -- create and bulk-create endpoints, -- full update and partial update endpoints, -- read endpoints for single records and filtered lists, -- soft delete and recovery endpoints, -- auth decorators, -- Swagger decorators, -- and file upload handling where required by field metadata. + - Create and bulk-create endpoints + - Full update and partial update endpoints + - Read endpoints for single records and filtered lists + - Soft delete and recovery endpoints + - Auth decorators + - Swagger decorators + - File upload handling where required by field metadata -In practice, the controller is the generated HTTP layer for a model. + In practice, the controller is the generated HTTP layer for a model. -### Service + + -Generated services usually extend `CRUDService` from `@solidxai/core`. + Generated services usually extend `CRUDService` from `@solidxai/core`. -That gives each model a metadata-aware service layer with: + That gives each model a metadata-aware service layer with: -- standard CRUD behavior, -- query parsing, -- soft delete and recovery support, -- media/file handling, -- and integration with module/model metadata services. + - Standard CRUD behavior + - Query parsing + - Soft delete and recovery support + - Media/file handling + - Integration with module/model metadata services -This is the generated business layer that sits between the controller and the repository. + This is the generated business layer that sits between the controller and the repository. -### DTOs + + -Each model gets a create and update DTO. + Each model gets a create and update DTO. -- The create DTO represents the required and optional data for creation. -- The update DTO mirrors the same fields but generally treats them as optional and includes the record `id`. -- Validation decorators and Swagger decorators are generated from field configuration. + - The create DTO represents the required and optional data for creation + - The update DTO mirrors the same fields but generally treats them as optional and includes the record `id` + - Validation decorators and Swagger decorators are generated from field configuration -These files are directly affected when fields are added, removed, or their types change. + These files are directly affected when fields are added, removed, or their types change. -### Entity + + -The generated entity maps model metadata into a TypeORM entity. + The generated entity maps model metadata into a TypeORM entity. -This includes: + This includes: -- column definitions, -- relation decorators such as `@ManyToOne`, -- nullability, -- indexes, -- uniqueness constraints, -- and inherited common fields such as audit and soft-delete support. + - Column definitions + - Relation decorators such as `@ManyToOne` + - Nullability + - Indexes + - Uniqueness constraints + - Inherited common fields such as audit and soft-delete support -This is the database-facing representation of the model. + This is the database-facing representation of the model. -### Repository + + -Generated repositories inherit from `SolidBaseRepository` and provide the data-access layer for the model. + Generated repositories inherit from `SolidBaseRepository` and provide the data-access layer for the model. -They already come with: + They already come with: -- metadata-aware TypeORM behavior, -- security-rule aware queries, -- request-context integration, -- and a clean place to add project-specific query methods later. + - Metadata-aware TypeORM behavior + - Security-rule aware queries + - Request-context integration + - A clean place to add project-specific query methods later + + + ## How Field Changes Affect Generated Files One useful way to think about code generation is this: -- module metadata defines the model, -- model metadata defines the fields, -- field changes flow into generated backend files. +- Module metadata defines the model. +- Model metadata defines the fields. +- Field changes flow into generated backend files. When you add or modify a field, SolidX typically updates: @@ -164,9 +180,9 @@ solid-api/src// Examples: -- adding a new string field usually adds validation decorators to both DTOs and a matching column in the entity, -- changing a field from text to number updates the DTO validation decorators and the entity column type, -- adding a relation field changes both entity decorators and the expected DTO shape. +- Adding a new string field usually adds validation decorators to both DTOs and a matching column in the entity. +- Changing a field from text to number updates the DTO validation decorators and the entity column type. +- Adding a relation field changes both entity decorators and the expected DTO shape. ## Layout Metadata Generated Alongside Models @@ -174,10 +190,10 @@ Although `solid-ui` itself is not generated the same way, model generation often Typical generated layout metadata includes: -- list view layout definitions, -- form view layout definitions, -- column/filter/search configuration, -- and default field placement for forms. +- List view layout definitions. +- Form view layout definitions. +- Column/filter/search configuration. +- Default field placement for forms. Those layouts define how generated admin screens behave, even though the project-specific React code in `solid-ui` is maintained separately. @@ -196,11 +212,12 @@ The SolidX code builder can be triggered from the admin experience or from the C ``` Use when: - - a module has been added - - multiple models in a module have changed - - fields have changed - - generated files have fallen out of sync with metadata - - or you want the safest full refresh path + + - A module has been added + - Multiple models in a module have changed + - Fields have changed + - Generated files have fallen out of sync with metadata + - You want the safest full refresh path } title="generate model (Targeted Refresh)"> Refreshes a single model and its related models. @@ -210,9 +227,10 @@ The SolidX code builder can be triggered from the admin experience or from the C ``` Use when: - - only one model has changed - - you want a faster refresh than regenerating the full module - - or you are iterating on one model repeatedly during development + + - Only one model has changed + - You want a faster refresh than regenerating the full module + - You are iterating on one model repeatedly during development @@ -240,7 +258,7 @@ Related docs: ## solid-ui Structure and Conventions -Even though SolidX does not auto-generate app-specific React modules in the same way, `solid-ui` still follows a predictable structure. Repeating this here is intentional, because understanding the backend generation story is much easier when you can also see how the frontend plugs into it. +Even though SolidX does not auto-generate app-specific React modules in the same way, `solid-ui` still follows a predictable structure. Understanding the backend generation story is much easier when you can also see how the frontend plugs into it. ### High-Level Structure @@ -273,11 +291,11 @@ This mounts the React application. This is the main application shell. It typically wires together: -- the router, -- store provider, -- theme and layout providers, -- application event listeners, -- and the route tree. +- The router. +- Store provider. +- Theme and layout providers. +- Application event listeners. +- The route tree. #### `src/AppRoutes.tsx` @@ -304,12 +322,12 @@ Each project-specific frontend module typically exports a default object from a That module can contribute: -- extra routes, -- extension components, -- extension functions, -- reducers, -- middleware, -- and any other runtime pieces expected by `@solidxai/core-ui`. +- Extra routes. +- Extension components. +- Extension functions. +- Reducers. +- Middleware. +- Any other runtime pieces expected by `@solidxai/core-ui`. Conceptually, a UI module is the frontend equivalent of a project feature package. @@ -332,55 +350,63 @@ src/venue/ ### What Belongs in Each Folder? -#### `*.ui-module.ts` + + + + This is the registration file for the frontend module. It usually defines: -This is the registration file for the frontend module. It usually defines: + - Module name + - Extra routes + - Extension components + - Extension functions + - Reducers + - Middleware -- module name, -- extra routes, -- extension components, -- extension functions, -- reducers, -- and middleware. + + -#### `admin-layout/` + Use this for code that extends or customizes generated admin screens. -Use this for code that extends or customizes generated admin screens. + Typical examples: -Typical examples: + - Custom list header actions + - Form widgets + - Form load handlers + - Field change handlers + - Model-specific admin behavior -- custom list header actions, -- form widgets, -- form load handlers, -- field change handlers, -- model-specific admin behavior. + + -#### `custom-layout/` + Use this for pages that are fully custom and not just tweaks to generated admin screens. -Use this for pages that are fully custom and not just tweaks to generated admin screens. + Typical examples: -Typical examples: + - Dashboards + - Login overrides + - Landing pages + - Custom home screens + - Business-specific workflows -- dashboards, -- login overrides, -- landing pages, -- custom home screens, -- or business-specific workflows. + + -#### `redux/` + Use this for RTK Query APIs and other Redux logic owned by the module. -Use this for RTK Query APIs and other Redux logic owned by the module. + These reducers and middleware are commonly surfaced through the module registration file so the app shell can compose them into the global store. -These reducers and middleware are commonly surfaced through the module registration file so the app shell can compose them into the global store. + + -#### `utils/` + Use this for module-specific utilities such as: -Use this for module-specific utilities such as: + - Export helpers + - Data-formatting helpers + - Display helpers + - Small reusable module-level functions -- export helpers, -- data-formatting helpers, -- display helpers, -- and small reusable module-level functions. + + ## Recommended Mental Model @@ -388,11 +414,11 @@ The cleanest way to think about the two apps together is: - `solid-api` is metadata-driven and heavily generated, - `solid-ui` is convention-driven and manually extended, -- generated layouts and APIs connect the two, -- and project-specific customization lives in extension points around that generated core. +- Generated layouts and APIs connect the two, +- Project-specific customization lives in extension points around that generated core. That division is important: -- backend generation gives you consistency and speed, -- frontend module conventions give you flexibility, -- and the shared `@solidxai/core-ui` runtime keeps the UI pluggable. +- Backend generation gives you consistency and speed. +- Frontend module conventions give you flexibility. +- The shared `@solidxai/core-ui` runtime keeps the UI pluggable. diff --git a/content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.md b/content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.mdx similarity index 85% rename from content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.md rename to content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.mdx index fc1fee7..f51cb8d 100644 --- a/content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.md +++ b/content/docs/developer-docs/extending/frontend-customization/bespoke-frontend-ui.mdx @@ -22,10 +22,20 @@ This pattern is intended for app-like experiences (for example merchant apps, ki For bespoke UIs, follow this operating model: -1. Create a dedicated layout component and wrapper with its own CSS. -2. Keep bespoke route-level UI under `src//custom-layout//...`. -3. Register bespoke routes in the owning module manifest (`.ui-module.ts`). -4. Build pages as pure React and use Solid HTTP helpers for backend calls. + + + Create a dedicated layout component and wrapper with its own CSS. + + + Keep bespoke route-level UI under `src//custom-layout//...`. + + + Register bespoke routes in the owning module manifest (`.ui-module.ts`). + + + Build pages as pure React and use Solid HTTP helpers for backend calls. + + ## Where Files Should Live @@ -169,8 +179,14 @@ No metadata schema is required for these pages. Solid supports both of these patterns for bespoke frontend work: -1. Solid HTTP helpers for direct promise-based API calls -2. Redux / RTK Query integration through module-owned reducers and middleware + + + Solid HTTP helpers for direct promise-based API calls. + + + Redux and RTK Query integration through module-owned reducers and middleware. + + This is a developer choice. Both are valid and supported. @@ -237,10 +253,10 @@ The runtime aggregates these registrations and passes them to `StoreProvider` th Use this style when you want: -- shared API state across multiple screens -- caching and invalidation -- generated query/mutation hooks -- a more structured app-wide API layer +- Shared API state across multiple screens +- Caching and invalidation +- Generated query/mutation hooks +- A more structured app-wide API layer For a full walkthrough, see [Redux Module Integration](./redux-module-integration.md). For direct API helpers, see [Solid HTTP API](./solid-http-api.md). @@ -280,13 +296,29 @@ You can combine both approaches in one application. ## Checklist -1. Create `Layout.tsx` + `LayoutWrapper.tsx` + dedicated CSS under `src//custom-layout//`. -2. Register nested routes in `.ui-module.ts` under `routes.extraRoutes`. -3. Ensure `solid-ui/src/solid-ui-modules.ts` aggregates module manifests. -4. Keep `AppRoutes.tsx` beside `App.tsx` and use `getSolidRoutes(solidUiModuleRuntime.routes)`. -5. Ensure routes are grouped under a clear base path (`//...`). -6. Build pages as React components. -7. Choose either direct Solid HTTP helpers or module-owned Redux / RTK Query integration. + + + Create `Layout.tsx` + `LayoutWrapper.tsx` + dedicated CSS under `src//custom-layout//`. + + + Register nested routes in `.ui-module.ts` under `routes.extraRoutes`. + + + Ensure `solid-ui/src/solid-ui-modules.ts` aggregates module manifests. + + + Keep `AppRoutes.tsx` beside `App.tsx` and use `getSolidRoutes(solidUiModuleRuntime.routes)`. + + + Ensure routes are grouped under a clear base path (`//...`). + + + Build pages as React components. + + + Choose either direct Solid HTTP helpers or module-owned Redux / RTK Query integration. + + ## See Also diff --git a/content/docs/developer-docs/extending/frontend-customization/custom-views.md b/content/docs/developer-docs/extending/frontend-customization/custom-views.mdx similarity index 85% rename from content/docs/developer-docs/extending/frontend-customization/custom-views.md rename to content/docs/developer-docs/extending/frontend-customization/custom-views.mdx index c9e17a8..6edbf87 100644 --- a/content/docs/developer-docs/extending/frontend-customization/custom-views.md +++ b/content/docs/developer-docs/extending/frontend-customization/custom-views.mdx @@ -11,13 +11,22 @@ solidx_concerns: [frontend.custom_pages, add_full_custom_ui, create_custom_widge In older discussions, "custom view" is used for two different patterns: -1. Metadata-driven custom UI blocks inside form/list layouts. -2. Fully bespoke route pages with independent layout/navigation. + + + Metadata-driven custom UI blocks inside form and list layouts. + + + Fully bespoke route pages with independent layout and navigation. + + Use the correct implementation path below. ## Decision Guide + + + ### Use Custom Widget (metadata-driven form-view block) Choose this when UI is rendered inside an existing form-view layout node with `type: "custom"` and should remain inside the generated Solid form flow. @@ -35,6 +44,9 @@ Use this path for: - field widgets - kanban card widgets + + + ### Use Custom Page (bespoke routing) Choose this when you need a dedicated page shell, route group, or custom navigation unrelated to metadata widgets. @@ -46,18 +58,25 @@ Choose this when you need a dedicated page shell, route group, or custom navigat See [Bespoke Frontend UI](./bespoke-frontend-ui.md) for the full route-level pattern. + + + ## API Convention for Both Paths For frontend API calls, Solid supports both of these patterns: -1. Direct Solid HTTP helpers from `@solidxai/core-ui` -2. Module-owned Redux / RTK Query integration under `solid-ui/src//redux/` + + + Direct Solid HTTP helpers from `@solidxai/core-ui`. + + + Module-owned Redux and RTK Query integration under `solid-ui/src//redux/`. + + ### Option A: Solid HTTP Helpers -Use: - -- `solidGet`, `solidPost`, `solidPut`, `solidPatch`, `solidDelete`, `solidAxios` +Use `solidGet`, `solidPost`, `solidPut`, `solidPatch`, `solidDelete`, `solidAxios` Guidelines: @@ -78,10 +97,10 @@ Then register reducers and middleware in `.ui-module.ts`. Choose this when you want: -- shared API state -- caching and invalidation -- generated hooks -- a more structured app-wide API layer +- Shared API state +- Caching and invalidation +- Generated hooks +- A more structured app-wide API layer See [Redux Module Integration](./redux-module-integration.md) for the full pattern. diff --git a/content/docs/developer-docs/extending/frontend-customization/custom-widgets.md b/content/docs/developer-docs/extending/frontend-customization/custom-widgets.mdx similarity index 95% rename from content/docs/developer-docs/extending/frontend-customization/custom-widgets.md rename to content/docs/developer-docs/extending/frontend-customization/custom-widgets.mdx index edfbca8..032876d 100644 --- a/content/docs/developer-docs/extending/frontend-customization/custom-widgets.md +++ b/content/docs/developer-docs/extending/frontend-customization/custom-widgets.mdx @@ -88,8 +88,14 @@ Always derive context from incoming props (for example `formData`, `field`, or m When widgets need backend calls, Solid supports both of these patterns: -1. Direct Solid HTTP helpers from `@solidxai/core-ui` -2. Module-owned Redux / RTK Query integration under `solid-ui/src//redux/` + + + Direct Solid HTTP helpers from `@solidxai/core-ui`. + + + Module-owned Redux and RTK Query integration under `solid-ui/src//redux/`. + + ### Option A: Solid HTTP Helpers diff --git a/content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.md b/content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.mdx similarity index 94% rename from content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.md rename to content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.mdx index 9a942c7..64a3583 100644 --- a/content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.md +++ b/content/docs/developer-docs/extending/frontend-customization/extension-ui-guidelines.mdx @@ -24,9 +24,9 @@ Recommended defaults: - `size="sm"` - `variant="outline"` or `variant="ghost"` -- content-based width -- single-line labels -- concise text +- Content-based width +- Single-line labels +- Concise text Example: @@ -48,9 +48,9 @@ SolidX already opens a popup container for your extension component. Render popu ### Popup content structure -- header: icon and title -- body: clear confirmation, success, or error message -- footer: right-aligned actions such as `Cancel`, `Confirm`, or `Close` +- Header: icon and title +- Body: clear confirmation, success, or error message +- Footer: right-aligned actions such as `Cancel`, `Confirm`, or `Close` Recommended wrapper: @@ -147,7 +147,7 @@ export function SeedCurrencyRates({ rowData }: any) { Apply these conventions to: - `solid-ui/src//admin-layout//extension-components/` -- popup-style action components rendered by metadata +- Popup-style action components rendered by metadata - UI rendered by handlers in `extension-functions/` when they drive popup or dynamic extension behavior ## See Also diff --git a/content/docs/developer-docs/extending/frontend-customization/form-view-buttons.md b/content/docs/developer-docs/extending/frontend-customization/form-view-buttons.mdx similarity index 90% rename from content/docs/developer-docs/extending/frontend-customization/form-view-buttons.md rename to content/docs/developer-docs/extending/frontend-customization/form-view-buttons.mdx index 711b3a1..485eac4 100644 --- a/content/docs/developer-docs/extending/frontend-customization/form-view-buttons.md +++ b/content/docs/developer-docs/extending/frontend-customization/form-view-buttons.mdx @@ -18,12 +18,20 @@ Do not place model-scoped form button components in generic folders. ## Default Implementation Flow -1. Create or update a React TSX component under: - - `solid-ui/src//admin-layout//extension-components/` -2. Keep export/import style consistent with neighboring files in that model folder. -3. Register the component in the owning UI module manifest: - - `solid-ui/src//.ui-module.ts` -4. Keep the registration name aligned with the form layout metadata `action` value. + + + Create or update a React TSX component under `solid-ui/src//admin-layout//extension-components/`. + + + Keep export and import style consistent with neighboring files in that model folder. + + + Register the component in the owning UI module manifest at `solid-ui/src//.ui-module.ts`. + + + Keep the registration name aligned with the form layout metadata `action` value. + + ## Component Props Contract diff --git a/content/docs/developer-docs/extending/frontend-customization/form-view-events.mdx b/content/docs/developer-docs/extending/frontend-customization/form-view-events.mdx index 67cebfa..e7500c6 100644 --- a/content/docs/developer-docs/extending/frontend-customization/form-view-events.mdx +++ b/content/docs/developer-docs/extending/frontend-customization/form-view-events.mdx @@ -20,9 +20,17 @@ You author **listener functions**, register them in the owning UI module manifes SolidX currently supports these form view events: -1. **`onFormLoad`** - unified form-load lifecycle event (recommended for all load-time logic). -2. **`onFieldChange`** - fires whenever a field **value changes**. -3. **`onFieldBlur`** - fires when a field **loses focus**. + + + **`onFormLoad`** - unified form-load lifecycle event, recommended for all load-time logic. + + + **`onFieldChange`** - fires whenever a field **value changes**. + + + **`onFieldBlur`** - fires when a field **loses focus**. + + @@ -37,10 +45,20 @@ Inside `SolidFormView`, form-load handlers run with a working layout/data contex Current execution sequence: -1. `onFormLayoutLoad` (legacy compatibility hook) -2. `onFormDataLoad` (legacy compatibility hook) -3. `onFormLoad` (recommended unified hook) -4. Commit final `workingLayout` and `workingFormData` to React state + + + `onFormLayoutLoad` (legacy compatibility hook). + + + `onFormDataLoad` (legacy compatibility hook). + + + `onFormLoad` (recommended unified hook). + + + Commit final `workingLayout` and `workingFormData` to React state. + + This means `onFormLoad` sees the latest working layout/data and is the best place for load-time logic moving forward. @@ -55,11 +73,17 @@ This means `onFormLoad` sees the latest working layout/data and is the best plac Default file selection for form event changes: -1. Create or update a TS/TSX listener inside: - - `solid-ui/src//admin-layout//extension-functions/` -2. Register the listener in the owning UI module manifest: - - `solid-ui/src//.ui-module.ts` -3. Keep the registration name aligned with layout metadata event references (`onFormLoad`, `onFieldChange`, `onFieldBlur`). + + + Create or update a TS or TSX listener inside `solid-ui/src//admin-layout//extension-functions/`. + + + Register the listener in the owning UI module manifest at `solid-ui/src//.ui-module.ts`. + + + Keep the registration name aligned with layout metadata event references such as `onFormLoad`, `onFieldChange`, and `onFieldBlur`. + + Example structure: @@ -198,10 +222,11 @@ Reference your handler name in the layout JSON: } ``` -'> **Note** + -''> Your handler can be one function that switches on `event.type`, or multiple functions registered under different names. -' +Your handler can be one function that switches on `event.type`, or multiple functions registered under different names. + + ## Event Payload (Types) @@ -271,10 +296,20 @@ Recommended metadata pattern: Migration guidance: -1. Move load-time layout logic from `onFormLayoutLoad` into `onFormLoad`. -2. Move load-time data shaping logic from `onFormDataLoad` into `onFormLoad`. -3. Keep `onFieldChange` and `onFieldBlur` unchanged. -4. Remove deprecated hooks from metadata once migration is complete. + + + Move load-time layout logic from `onFormLayoutLoad` into `onFormLoad`. + + + Move load-time data shaping logic from `onFormDataLoad` into `onFormLoad`. + + + Keep `onFieldChange` and `onFieldBlur` unchanged. + + + Remove deprecated hooks from metadata once migration is complete. + + ## Common Patterns @@ -285,10 +320,10 @@ Migration guidance: ## Troubleshooting -- **My changes are not applied** -> Verify `layoutChanged`/`dataChanged` flags and corresponding payloads are returned. -- **Load-time logic is not running** -> Ensure the layout has `onFormLoad` and the handler name matches the registered manifest entry. -- **Node not found** -> Verify the node ID passed to `updateNodeAttributes` exists in the layout tree. -- **Nothing happens on change** -> Confirm `onFieldChange` is mapped and the handler checks the correct field name. +- **My changes are not applied** - Verify `layoutChanged`/`dataChanged` flags and corresponding payloads are returned. +- **Load-time logic is not running** - Ensure the layout has `onFormLoad` and the handler name matches the registered manifest entry. +- **Node not found** - Verify the node ID passed to `updateNodeAttributes` exists in the layout tree. +- **Nothing happens on change** - Confirm `onFieldChange` is mapped and the handler checks the correct field name. ## See Also diff --git a/content/docs/developer-docs/extending/frontend-customization/form-view-field-widgets.mdx b/content/docs/developer-docs/extending/frontend-customization/form-view-field-widgets.mdx index 03039e1..0ff78f6 100644 --- a/content/docs/developer-docs/extending/frontend-customization/form-view-field-widgets.mdx +++ b/content/docs/developer-docs/extending/frontend-customization/form-view-field-widgets.mdx @@ -11,15 +11,15 @@ solidx_concerns: [frontend.extensions.custom_widgets, create_custom_form_field_w Form view field widgets let you customize how fields are displayed inside a form view. They support both: -- **edit mode** via `editWidget` -- **view mode** via `viewWidget` +- **Edit mode** via `editWidget` +- **View mode** via `viewWidget` You can use either: -- **built-in widgets** provided by the framework, or -- **custom widgets** that you create and register through the owning UI module manifest. +- **Built-in widgets** provided by the framework, or +- **Custom widgets** that you create and register through the owning UI module manifest. -Example: display an integer field `score` as a slider using the built-in `integerSlider` widget. +Example: Display an integer field `score` as a slider using the built-in `integerSlider` widget. ```json { @@ -50,6 +50,9 @@ In the above example, the `editWidget` attribute specifies the widget to use in SolidX ships with a set of pre-built widgets for many field types. You can reference these directly in the layout JSON without writing or registering any code. + + + ### Edit Widgets (`editWidget`) Used in edit mode via the `editWidget` attribute on a form field. @@ -94,6 +97,9 @@ Used in edit mode via the `editWidget` attribute on a form field. + + + ### View Widgets (`viewWidget`) Used in read-only mode via the `viewWidget` attribute on a form field. @@ -126,6 +132,9 @@ Used in read-only mode via the `viewWidget` attribute on a form field. + + + ## Creating a Custom Widget ### 1. Create the Widget Component @@ -235,12 +244,27 @@ solid-api/module-metadata//-metadata.json ## How It Works -1. SolidX loads the form layout in edit mode. -2. It identifies fields with an `editWidget` or `viewWidget`. -3. It resolves the registered widget component by name or alias. -4. The widget is rendered with props of type `SolidFormFieldWidgetProps`. -5. The widget applies your custom rendering logic. -6. Default widgets are also rendered using the same mechanism. + + + SolidX loads the form layout in edit mode. + + + It identifies fields with an `editWidget` or `viewWidget`. + + + It resolves the registered widget component by name or alias. + + + The widget is rendered with props of type `SolidFormFieldWidgetProps`. + + + The widget applies your custom rendering logic. + + + + + Default widgets are also rendered using the same mechanism. + ## Widget Props Contract @@ -266,10 +290,10 @@ export type SolidFieldProps = { Guidance: -- use `fieldContext.fieldMetadata` for field constraints and display metadata -- use `fieldContext.field` for layout attributes such as label and widget choice -- use `formik.values` and `formik.setFieldValue(...)` for form state changes -- respect `readOnly`, validation, and required-state behavior +- Use `fieldContext.fieldMetadata` for field constraints and display metadata +- Use `fieldContext.field` for layout attributes such as label and widget choice +- Use `formik.values` and `formik.setFieldValue(...)` for form state changes +- Respect `readOnly`, validation, and required-state behavior ## View Widgets (Read-Only Mode) @@ -309,11 +333,7 @@ Use `solidGet`, `solidPost`, `solidPut`, `solidPatch`, `solidDelete`, or `solidA ### Option B: Redux / RTK Query -If the widget participates in a wider module-owned data flow, place RTK Query APIs, reducers, and middleware under: - -- `solid-ui/src//redux/` - -and register them through the same UI module manifest. +If the widget participates in a wider module-owned data flow, place RTK Query APIs, reducers, and middleware under `solid-ui/src//redux/` and register them through the same UI module manifest. See also: [Redux Module Integration](./redux-module-integration.md) and [Solid HTTP API](./solid-http-api.md) diff --git a/content/docs/developer-docs/extending/frontend-customization/index.mdx b/content/docs/developer-docs/extending/frontend-customization/index.mdx index 13a9690..39bab80 100644 --- a/content/docs/developer-docs/extending/frontend-customization/index.mdx +++ b/content/docs/developer-docs/extending/frontend-customization/index.mdx @@ -1,10 +1,12 @@ --- title: Frontend icon: "palette" -description: Catalog of frontend customization patterns in SolidX. -summary: "Entry point for metadata-driven extensions and bespoke frontend UIs in SolidX, including module-based file-location rules, manifest registration patterns, and API-call conventions." +description: Reference for frontend customization patterns in SolidX. +summary: "Covers metadata-driven UI extensions, custom frontend components, module file-location rules, manifest registration, and frontend integration conventions." --- +import { Boxes, Component, Route, Workflow } from 'lucide-react'; + ## Frontend Customization Catalog Use this section as the source of truth for where each customization type belongs and how it should be wired in the UI module system. @@ -12,30 +14,51 @@ Use this section as the source of truth for where each customization type belong The SolidX frontend is designed so that custom UI code stays close to the module that owns the business feature. - Instead of scattering custom screens, reducers, and extension widgets across the app, the convention keeps each feature grouped together. + - Use metadata-driven extensions when you are augmenting generated admin screens. - - Use bespoke UI when you need full route-level control. - - Keep ownership module-local so discovery, registration, and maintenance stay predictable. - So the intuition is: the UI stays flexible because SolidX combines generated structure with module-owned custom code. + - Use bespoke UI when you need full route-level control. + - Keep ownership module-local so discovery, registration, and maintenance stay predictable. + + The UI stays flexible because SolidX combines generated structure with module-owned custom code. +## Customization Modes + + + } title="Metadata-Driven Extensions"> + Use buttons, widgets, and event hooks to extend generated forms, lists, trees, and kanban views without replacing them. + + } title="Bespoke Screens"> + Create custom route-level pages when generated admin views are not the right fit for the workflow. + + } title="State and API Integration"> + Register Redux, RTK Query, and Solid HTTP helpers at the module level so custom UI stays composable. + + } title="Module-Owned Structure"> + Keep routes, widgets, actions, reducers, and extension functions inside the owning module folder. + + + ## UI Module Convention In the current SolidX frontend model, custom frontend code should be organized inside module folders under `solid-ui/src//`. Recommended structure: -```text +```bash solid-ui/src/ - / - admin-layout/ - custom-layout/ - redux/ - .ui-module.ts +├── App.tsx # Application shell and providers +├── AppRoutes.tsx # Route composition entry +├── solid-ui-modules.ts # Module discovery and runtime aggregation +├── / +│ ├── admin-layout/ # Metadata-driven admin extensions +│ ├── custom-layout/ # Bespoke route-level pages and shells +│ ├── redux/ # Module-owned reducers, middleware, RTK Query APIs +│ └── .ui-module.ts # Module manifest for routes and extensions ``` -Use these responsibilities: +Use these structure conventions: - `admin-layout/` for metadata-driven admin extensions such as buttons, event handlers, and widgets - `custom-layout/` for bespoke route-level UIs and custom application shells diff --git a/content/docs/developer-docs/extending/frontend-customization/kanban-card-widget.md b/content/docs/developer-docs/extending/frontend-customization/kanban-card-widget.mdx similarity index 100% rename from content/docs/developer-docs/extending/frontend-customization/kanban-card-widget.md rename to content/docs/developer-docs/extending/frontend-customization/kanban-card-widget.mdx diff --git a/content/docs/developer-docs/extending/frontend-customization/layout-manager.md b/content/docs/developer-docs/extending/frontend-customization/layout-manager.mdx similarity index 86% rename from content/docs/developer-docs/extending/frontend-customization/layout-manager.md rename to content/docs/developer-docs/extending/frontend-customization/layout-manager.mdx index d54fe3a..18cca63 100644 --- a/content/docs/developer-docs/extending/frontend-customization/layout-manager.md +++ b/content/docs/developer-docs/extending/frontend-customization/layout-manager.mdx @@ -20,8 +20,8 @@ Typical locations in the UI module system: Typical event hooks: -- form listeners such as `onFormLoad`, `onFieldChange`, and `onFieldBlur` -- list listeners such as `onBeforeListDataLoad` and `onListLoad` when layout updates are needed +- Form listeners such as `onFormLoad`, `onFieldChange`, and `onFieldBlur` +- List listeners such as `onBeforeListDataLoad` and `onListLoad` when layout updates are needed ## Form Example @@ -63,9 +63,9 @@ export function handleBookListEvents(event: any) { Without flags, changes are ignored by the runtime. -- layout mutation: return `layoutChanged: true` with `newLayout` -- data mutation: return `dataChanged: true` with full `newFormData` or `newListData` -- filter override for list prefetch: return `filterApplied: true` with `newFilter` +- Layout mutation: return `layoutChanged: true` with `newLayout` +- Data mutation: return `dataChanged: true` with full `newFormData` or `newListData` +- Filter override for list prefetch: return `filterApplied: true` with `newFilter` ## Safety Guidance diff --git a/content/docs/developer-docs/extending/frontend-customization/list-view-api.md b/content/docs/developer-docs/extending/frontend-customization/list-view-api.mdx similarity index 77% rename from content/docs/developer-docs/extending/frontend-customization/list-view-api.md rename to content/docs/developer-docs/extending/frontend-customization/list-view-api.mdx index 7e33cf4..859e17f 100644 --- a/content/docs/developer-docs/extending/frontend-customization/list-view-api.md +++ b/content/docs/developer-docs/extending/frontend-customization/list-view-api.mdx @@ -1,7 +1,7 @@ --- title: List API icon: "code" -description: Learn how to access and control SolidX list views programmatically from external components. +description: Reference for accessing and controlling SolidX list views programmatically from external components. summary: "Documents how SolidX exposes list view handles through `listViewRegistry` for external usage. Covers `getListView`, `getRegisteredListViewIds`, list ID format, `SolidListViewHandle` methods, and practical integration patterns." solidx_concerns: [frontend.extensions.list_buttons, frontend.extensions.row_buttons, frontend.custom_pages, add_list_header_button_with, add_list_row_button_with, create_custom_widget] --- @@ -12,9 +12,9 @@ SolidX exposes a programmatic List View API so external components can control a Typical callers now include: -- module-owned list buttons under `admin-layout` -- custom widgets under `admin-layout` -- bespoke route UIs under `custom-layout` +- Module-owned list buttons under `admin-layout` +- Custom widgets under `admin-layout` +- Bespoke route UIs under `custom-layout` This API is exposed through: @@ -50,7 +50,7 @@ Important details: - `modelName` is camel-cased in `ListPage` - `menuItemId`, `menuItemName`, `actionId`, and `actionName` are part of the ID -- treat list IDs as fully-qualified keys and use exact matching +- Treat list IDs as fully-qualified keys and use exact matching ## Registry API @@ -87,10 +87,20 @@ type SolidListViewHandle = { Pattern: -1. Read registered IDs. -2. Build the exact target `listId` from module, model, menu, and action context. -3. Resolve the handle via `getListView`. -4. Invoke handle APIs such as `applyFilter` or `refresh`. + + + Read registered IDs. + + + Build the exact target `listId` from module, model, menu, and action context. + + + Resolve the handle via `getListView`. + + + Invoke handle APIs such as `applyFilter` or `refresh`. + + Example: @@ -121,10 +131,10 @@ if (listView) { ## Troubleshooting -- list handle is `undefined` -> list may not be mounted yet or the ID does not match exactly -- no matching ID found -> inspect `getRegisteredListViewIds()` and verify every segment -- filter call has no effect -> verify predicate structure and target model field names -- wrong target list updated -> use exact `listId` matching only +- List handle is `undefined` -> list may not be mounted yet or the ID does not match exactly +- No matching ID found -> inspect `getRegisteredListViewIds()` and verify every segment +- Filter call has no effect -> verify predicate structure and target model field names +- Wrong target list updated -> use exact `listId` matching only ## Related diff --git a/content/docs/developer-docs/extending/frontend-customization/list-view-buttons.md b/content/docs/developer-docs/extending/frontend-customization/list-view-buttons.mdx similarity index 90% rename from content/docs/developer-docs/extending/frontend-customization/list-view-buttons.md rename to content/docs/developer-docs/extending/frontend-customization/list-view-buttons.mdx index 99a639c..719ca6c 100644 --- a/content/docs/developer-docs/extending/frontend-customization/list-view-buttons.md +++ b/content/docs/developer-docs/extending/frontend-customization/list-view-buttons.mdx @@ -10,8 +10,14 @@ solidx_concerns: [frontend.extensions.list_buttons, frontend.extensions.row_butt List button customizations are model-scoped and split into two UI patterns: -1. Header or list-wide actions -2. Row-level actions + + + Header or list-wide actions. + + + Row-level actions. + + Both should live under the owning module's `admin-layout` folder. @@ -149,13 +155,11 @@ Rules: ### Option B: Redux / RTK Query -If the list action belongs to a module-owned API strategy, place RTK Query APIs, reducers, and middleware under: +Use this option when the list action belongs to a module-owned API strategy and should participate in shared cached state, invalidation, or coordinated refresh flows. -- `solid-ui/src//redux/` +Place RTK Query APIs, reducers, and middleware under `solid-ui/src//redux/`, and register them through the same module manifest. -and register them through the same module manifest. - -Use this when actions participate in shared cached state, invalidation, or coordinated refresh flows. +See [Redux Module Integration](./redux-module-integration.md) for the full module-owned pattern. ## UI Guidance diff --git a/content/docs/developer-docs/extending/frontend-customization/list-view-events.md b/content/docs/developer-docs/extending/frontend-customization/list-view-events.mdx similarity index 78% rename from content/docs/developer-docs/extending/frontend-customization/list-view-events.md rename to content/docs/developer-docs/extending/frontend-customization/list-view-events.mdx index 48e9d7c..45b808f 100644 --- a/content/docs/developer-docs/extending/frontend-customization/list-view-events.md +++ b/content/docs/developer-docs/extending/frontend-customization/list-view-events.mdx @@ -12,9 +12,9 @@ List view function extensions let you hook into list lifecycle events in SolidX. Use them to: -- modify the outgoing list query or filter before API fetch -- transform list records after they are loaded -- adjust list layout dynamically at runtime +- Modify the outgoing list query or filter before API fetch +- Transform list records after they are loaded +- Adjust list layout dynamically at runtime You author listener functions, register them in the owning UI module manifest, and reference them in your list view layout JSON. @@ -22,19 +22,39 @@ You author listener functions, register them in the owning UI module manifest, a Based on `SolidListView.tsx`, list view supports these lifecycle events: -1. `onBeforeListDataLoad` - runs just before the list API call. Best for filter and query shaping. -2. `onListLoad` - runs after list data is loaded. Best for data or layout transformation. + + + `onBeforeListDataLoad` - runs just before the list API call. Best for filter and query shaping. + + + `onListLoad` - runs after list data is loaded. Best for data or layout transformation. + + ## Event Execution Behavior Current list lifecycle flow: -1. List state is prepared. -2. `onBeforeListDataLoad` executes if configured. -3. If the handler returns `filterApplied: true` with `newFilter`, that filter object is used for the API request. -4. List API request runs. -5. `onListLoad` executes with fetched records. -6. If returned, `newListData` and or `newLayout` are committed to state. + + + List state is prepared. + + + `onBeforeListDataLoad` executes if configured. + + + If the handler returns `filterApplied: true` with `newFilter`, that filter object is used for the API request. + + + The list API request runs. + + + `onListLoad` executes with fetched records. + + + If returned, `newListData` and `newLayout` are committed to state. + + ## Project Structure & File Paths @@ -50,12 +70,12 @@ Example structure: ```text solid-ui/src/ - / - admin-layout/ - / - extension-functions/ - ListViewChangeHandler.ts - .ui-module.ts +└── / + ├── admin-layout/ + │ └── / + │ └── extension-functions/ + │ └── ListViewChangeHandler.ts + └── .ui-module.ts ``` ## Creating a Handler @@ -198,10 +218,10 @@ Usage rules: ## Common Patterns -- pre-filtering by tenant, role, or context in `onBeforeListDataLoad` -- enforcing default sort or locale-aware query options -- adding computed display-only properties in `onListLoad` -- runtime column visibility or label changes with `SolidViewLayoutManager` +- Pre-filtering by tenant, role, or context in `onBeforeListDataLoad` +- Enforcing default sort or locale-aware query options +- Adding computed display-only properties in `onListLoad` +- Runtime column visibility or label changes with `SolidViewLayoutManager` ## Troubleshooting diff --git a/content/docs/developer-docs/extending/frontend-customization/list-view-field-widgets.mdx b/content/docs/developer-docs/extending/frontend-customization/list-view-field-widgets.mdx index c289443..2db93ff 100644 --- a/content/docs/developer-docs/extending/frontend-customization/list-view-field-widgets.mdx +++ b/content/docs/developer-docs/extending/frontend-customization/list-view-field-widgets.mdx @@ -14,8 +14,8 @@ They are configured with the `viewWidget` attribute in list view layout JSON. You can use either: -- built-in widgets provided by `@solidxai/core-ui` -- custom widgets registered through the owning UI module manifest +- Built-in widgets provided by `@solidxai/core-ui` +- Custom widgets registered through the owning UI module manifest For example, to display a user's name with an avatar, you can use the built-in `SolidShortTextAvatarWidget`. @@ -150,10 +150,20 @@ export default libraryUiModule; ## How It Works -1. SolidX loads the list view layout. -2. It checks fields with a `viewWidget` attribute. -3. The registered widget component is resolved by name or alias. -4. The widget is rendered for each row with props of type `SolidListFieldWidgetProps`. + + + SolidX loads the list view layout. + + + It checks fields with a `viewWidget` attribute. + + + The registered widget component is resolved by name or alias. + + + The widget is rendered for each row with props of type `SolidListFieldWidgetProps`. + + ```tsx export type SolidListFieldWidgetProps = { @@ -181,11 +191,7 @@ Use `solidGet`, `solidPost`, `solidPut`, `solidPatch`, `solidDelete`, or `solidA ### Option B: Redux / RTK Query -If the widget participates in wider shared state, place RTK Query APIs, reducers, and middleware under: - -- `solid-ui/src//redux/` - -and register them through the same module manifest. +If the widget participates in wider shared state, place RTK Query APIs, reducers, and middleware under `solid-ui/src//redux/`, and register them through the same module manifest. ## Related diff --git a/content/docs/developer-docs/extending/frontend-customization/redux-module-integration.md b/content/docs/developer-docs/extending/frontend-customization/redux-module-integration.mdx similarity index 71% rename from content/docs/developer-docs/extending/frontend-customization/redux-module-integration.md rename to content/docs/developer-docs/extending/frontend-customization/redux-module-integration.mdx index 84398c9..e662404 100644 --- a/content/docs/developer-docs/extending/frontend-customization/redux-module-integration.md +++ b/content/docs/developer-docs/extending/frontend-customization/redux-module-integration.mdx @@ -10,23 +10,29 @@ solidx_concerns: [frontend.custom_pages, add_full_custom_ui, frontend.redux_modu SolidX supports two valid frontend API integration styles: -1. Direct promise-based API calls with Solid HTTP helpers such as `solidGet` and `solidPost` -2. Redux-based integration using RTK Query APIs, reducers, and middleware registered per UI module + + + Direct promise-based API calls with Solid HTTP helpers such as `solidGet` and `solidPost`. + + + Redux-based integration using RTK Query APIs, reducers, and middleware registered per UI module. + + Both are supported. The choice depends on how you want to structure the consuming app. Use Redux module integration when you want: -- shared cached API state -- generated query/mutation hooks -- reducer and middleware composition per module -- a consistent app-wide RTK Query pattern +- Shared cached API state +- Generated query/mutation hooks +- Reducer and middleware composition per module +- A consistent app-wide RTK Query pattern Use direct Solid HTTP helpers when you want: -- lightweight one-off API calls -- bespoke flows without centralized store concerns -- minimal setup for route-local or component-local logic +- Lightweight one-off API calls +- Bespoke flows without centralized store concerns +- Minimal setup for route-local or component-local logic ## Folder Convention @@ -38,21 +44,23 @@ solid-ui/src//redux/ Example from NBF: -```text -solid-ui/src/merchant-onboarding/redux/ - applicationApi.tsx - applicationBankApi.tsx - applicationLocationApi.tsx - applicationTerminalApi.tsx - -solid-ui/src/tranaction/redux/ - authApi.tsx - dynamicQrCodeApi.tsx - getTransactionApi.tsx - payByLinkApi.tsx - reportApi.tsx - requestToPayApi.tsx - staticQrApi.tsx +```bash +solid-ui/src/ +├── merchant-onboarding/ +│ └── redux/ +│ ├── applicationApi.tsx +│ ├── applicationBankApi.tsx +│ ├── applicationLocationApi.tsx +│ └── applicationTerminalApi.tsx +└── tranaction/ + └── redux/ + ├── authApi.tsx + ├── dynamicQrCodeApi.tsx + ├── getTransactionApi.tsx + ├── payByLinkApi.tsx + ├── reportApi.tsx + ├── requestToPayApi.tsx + └── staticQrApi.tsx ``` ## Module Manifest Registration @@ -160,26 +168,32 @@ export const { ## Choosing Between Solid HTTP and Redux -### Choose Solid HTTP helpers when: + + + +- The flow is local to one page or one component +- You do not need shared cached state +- You want a minimal promise-based implementation +- The API orchestration is custom or multi-step + + -- the flow is local to one page or one component -- you do not need shared cached state -- you want a minimal promise-based implementation -- the API orchestration is custom or multi-step + -### Choose Redux / RTK Query when: +- Multiple screens or components need the same API state +- You want generated hooks and caching +- You want tag-based invalidation and refetch behavior +- The project already uses module-owned RTK Query APIs as a standard -- multiple screens or components need the same API state -- you want generated hooks and caching -- you want tag-based invalidation and refetch behavior -- the project already uses module-owned RTK Query APIs as a standard + + Both approaches are valid in the same application. For example: -- a bespoke CMS homepage in `custom-layout/` may use `solidGet` directly -- a merchant workflow in `tranaction/redux/` may use RTK Query hooks for shared app state +- A bespoke CMS homepage in `custom-layout/` may use `solidGet` directly +- A merchant workflow in `tranaction/redux/` may use RTK Query hooks for shared app state ## Best Practices diff --git a/content/docs/developer-docs/extending/frontend-customization/solid-entity-api.md b/content/docs/developer-docs/extending/frontend-customization/solid-entity-api.mdx similarity index 80% rename from content/docs/developer-docs/extending/frontend-customization/solid-entity-api.md rename to content/docs/developer-docs/extending/frontend-customization/solid-entity-api.mdx index 8dc7891..3ae8c77 100644 --- a/content/docs/developer-docs/extending/frontend-customization/solid-entity-api.md +++ b/content/docs/developer-docs/extending/frontend-customization/solid-entity-api.mdx @@ -12,9 +12,9 @@ solidx_concerns: [frontend.custom_pages, add_full_custom_ui] Use it when you want: -- generated query and mutation hooks +- Generated query and mutation hooks - RTK Query caching and invalidation -- a reusable module-owned API layer under `solid-ui/src//redux/` +- A reusable module-owned API layer under `solid-ui/src//redux/` This pattern fits especially well with the new UI module system, where each module can own its own reducers, middleware, and API clients. @@ -57,16 +57,22 @@ export const createSolidEntityApi = (entityName: string) => { ## Endpoints and Semantics -### `getSolidEntities` + + -- method: GET -- use for list fetches, pagination, filtering, sorting, and grouping -- cache key is based on the query argument, typically the serialized query string +- Method: GET +- Use for list fetches, pagination, filtering, sorting, and grouping +- Cache key is based on the query argument, typically the serialized query string -### `getSolidEntityById` + -- method: GET -- use for entity detail fetches by ID + + +- Method: GET +- Use for entity detail fetches by ID + + + ### Mutations @@ -128,18 +134,18 @@ await createEntity(payload); Use Solid Entity API when: -- your use case matches standard entity list and detail patterns -- you want caching and invalidation automatically handled by RTK Query -- the module benefits from shared API state +- Your use case matches standard entity list and detail patterns +- You want caching and invalidation automatically handled by RTK Query +- The module benefits from shared API state Prefer direct HTTP helpers when the workflow is custom, multi-step, or not entity-shaped. See [Solid HTTP API](./solid-http-api.md). ## Best Practices -- keep serialization stable so cache keys remain predictable -- use `LIST` invalidation for collection refreshes -- invalidate both record and list tags on update or delete -- keep generated APIs close to the owning module +- Keep serialization stable so cache keys remain predictable +- Use `LIST` invalidation for collection refreshes +- Invalidate both record and list tags on update or delete +- Keep generated APIs close to the owning module ## Related diff --git a/content/docs/developer-docs/extending/frontend-customization/solid-http-api.md b/content/docs/developer-docs/extending/frontend-customization/solid-http-api.mdx similarity index 71% rename from content/docs/developer-docs/extending/frontend-customization/solid-http-api.md rename to content/docs/developer-docs/extending/frontend-customization/solid-http-api.mdx index ec6d7c4..f1c508c 100644 --- a/content/docs/developer-docs/extending/frontend-customization/solid-http-api.md +++ b/content/docs/developer-docs/extending/frontend-customization/solid-http-api.mdx @@ -12,15 +12,15 @@ The Solid HTTP API helpers provide a lightweight way to call backend APIs from c Use them when you want: -- direct promise-based API calls -- full control over when requests run -- custom workflows that do not fit a generated entity API pattern +- Direct promise-based API calls +- Full control over when requests run +- Custom workflows that do not fit a generated entity API pattern These helpers are commonly used from: -- extension components in `admin-layout` -- handler logic in `extension-functions` -- bespoke route UIs in `custom-layout` +- Extension components in `admin-layout` +- Handler logic in `extension-functions` +- Bespoke route UIs in `custom-layout` ## Helper Overview @@ -30,10 +30,10 @@ import { solidAxios, solidGet, solidPost, solidPut, solidPatch, solidDelete } fr `solidAxios` is a preconfigured Axios instance that: -- uses the configured backend base URL -- attaches the access token from session when available -- emits global error events on network errors or server failures -- normalizes accidental `/api` prefixes in request paths +- Uses the configured backend base URL +- Attaches the access token from session when available +- Emits global error events on network errors or server failures +- Normalizes accidental `/api` prefixes in request paths Convenience exports: @@ -45,22 +45,32 @@ Convenience exports: ## Methods and Semantics -### `solidGet` + + Use for reads such as list fetches, detail fetches, or lookup requests. -### `solidPost` + + + Use for creates, custom actions, or trigger endpoints. -### `solidPut` and `solidPatch` + + + Use for full or partial updates. -### `solidDelete` + + + Use for deletes or delete-like custom endpoints. + + + ## Building Query Strings and Filters You can either build a query string manually: @@ -145,24 +155,24 @@ const onSave = async () => { Use **Solid Entity API** when: -- you want generated CRUD hooks with RTK Query caching and auto-refetch -- your use case matches standard entity list or detail patterns -- you want module-owned reducers and middleware under `redux/` +- You want generated CRUD hooks with RTK Query caching and auto-refetch +- Your use case matches standard entity list or detail patterns +- You want module-owned reducers and middleware under `redux/` Use **Solid HTTP API** when: -- you need custom multi-step workflows or action endpoints -- you want direct promise-based control in component logic -- you are building one-off integration logic in widgets, buttons, dialogs, or bespoke route UIs +- You need custom multi-step workflows or action endpoints +- You want direct promise-based control in component logic +- You are building one-off integration logic in widgets, buttons, dialogs, or bespoke route UIs Both patterns are supported in the same app. This is a structural choice, not a framework limitation. ## Best Practices -- handle loading and errors explicitly -- use `qs.stringify(..., { encodeValuesOnly: true })` for filter-heavy endpoints -- prefer context-derived IDs over hardcoded values -- remember there is no automatic cache invalidation; manually refresh where needed +- Handle loading and errors explicitly +- Use `qs.stringify(..., { encodeValuesOnly: true })` for filter-heavy endpoints +- Prefer context-derived IDs over hardcoded values +- Remember there is no automatic cache invalidation; manually refresh where needed ## Related diff --git a/content/docs/developer-docs/extending/index.mdx b/content/docs/developer-docs/extending/index.mdx index ff55d6e..d3040dc 100644 --- a/content/docs/developer-docs/extending/index.mdx +++ b/content/docs/developer-docs/extending/index.mdx @@ -1,58 +1,44 @@ --- title: Extending SolidX icon: "puzzle-piece" -description: Guide to extending SolidX with custom code generation and frontend/backend customization. -summary: This document serves as an overview of SolidX extensibility features, explaining how to build custom functional modules and extend the platform capabilities. It highlights three main customization areas - Generated Code (using the code generation tool to scaffold controllers, services, entities, DTOs, and layout JSON files with default list and form views), Frontend Customization (modifying layout.json for custom list views, form layouts, kanban boards, and UI behaviors), and Backend Customization (extending NestJS backend with custom services, controllers, computed providers, middleware, and business logic). +description: Reference for extending SolidX through generated code, frontend customization, and backend customization. +summary: Covers the supported extension points for generated code, frontend modules, backend services, and other project-specific SolidX customization. --- -import { Cpu, Palette, Server } from 'lucide-react'; +import { BookOpen, Cpu, Palette, Server } from 'lucide-react'; - Extending SolidX is about deciding **where to keep the platform default behaviour** and **where to introduce project-specific logic**. - - **Generated code** gives you a strong starting structure. - - **Frontend customization** lets you tailor the user experience and module-specific UI. - - **Backend customization** lets you add domain logic, integrations, and behaviour beyond the generated defaults. - So the intuition is: SolidX gives you a metadata-driven base, and this section explains the supported places where you should extend it instead of fighting the framework. +Extending SolidX is primarily about choosing the correct layer for customization and preserving the distinction between metadata-driven behavior and project-specific implementation. + +- `Generated code` provides the baseline structure and default runtime composition. +- `Frontend customization` targets user-facing workflows, layout behavior, widgets, routes, and UI extensions. +- `Backend customization` targets domain logic, integrations, runtime policies, and non-declarative behavior. + +This section documents where customization belongs so implementation stays aligned with framework conventions rather than bypassing them. -This section outlines how to extend **SolidX** to build your own functional modules, such as a `school-fees-portal`. +This section outlines how to extend SolidX to build your own functional modules, such as a `school-fees-portal`. -SolidX offers a **powerful code generation tool** that enables rapid scaffolding of new modules with all the essential boilerplate. This accelerates your development by letting you focus directly on your specific **business logic**, without worrying about foundational setup. +SolidX provides a code-generation workflow that scaffolds the baseline structure for new modules so you can focus directly on business logic rather than foundational setup. -In addition to scaffolding, SolidX supports **deep customization** across both frontend and backend layers. You can tailor UI components, introduce new features, or adjust the behavior of existing elements to match your application's needs. +In addition to scaffolding, SolidX supports customization across both frontend and backend layers. You can tailor UI components, adjust generated behavior, or introduce project-specific runtime logic where the default platform behavior is not enough. -## Customization Capabilities +## Extension Areas -SolidX provides the following extensibility features: +SolidX provides the following extension areas: - } title="Generated Code"> - - Quickly scaffold new modules using the SolidX code generation tool. - - Auto-generates: - - Controllers - - Services - - Entities - - Data Transfer Objects - - Layout JSON files (for UI configuration) - - The default layout supports: - - List View - - Form View + } title="Code Generation" href="/docs/developer-docs/extending/code-generation"> + Generate the baseline structure for new modules and models, including controllers, services, entities, DTOs, repositories, and default frontend layout metadata. - } title="Frontend Customization"> - - Modify the generated `layout.json` to: - - Customize list views - - Tailor form layouts - - Configure kanban boards - - Add custom UI behaviors + } title="Frontend Customization" href="/docs/developer-docs/extending/frontend-customization"> + Customize generated UI behavior through layouts, widgets, buttons, routes, custom pages, event handlers, and other module-specific frontend extensions. - } title="Backend Customization"> - - Extend the NestJS backend by adding: - - Custom services and controllers - - Computed providers - - Middleware or interceptors - - Business-specific logic + } title="Backend Customization" href="/docs/developer-docs/extending/backend-customization"> + Extend the NestJS backend with services, controllers, providers, middleware, integrations, subscribers, scheduled jobs, and business-specific runtime behavior. + + } title="Built-in Reference" href="/docs/developer-docs/extending/reference"> + Review the built-in providers, widgets, primitives, and extension surfaces that already ship with SolidX before implementing custom versions. - -By leveraging these capabilities, you can build modular, scalable, and highly customized applications using the SolidX framework. diff --git a/content/docs/developer-docs/extending/reference/built-in-computation-providers.md b/content/docs/developer-docs/extending/reference/built-in-computation-providers.mdx similarity index 91% rename from content/docs/developer-docs/extending/reference/built-in-computation-providers.md rename to content/docs/developer-docs/extending/reference/built-in-computation-providers.mdx index 22ad943..95d945f 100644 --- a/content/docs/developer-docs/extending/reference/built-in-computation-providers.md +++ b/content/docs/developer-docs/extending/reference/built-in-computation-providers.mdx @@ -5,8 +5,7 @@ description: Reference for the built-in computation providers available in Solid keywords: [backend, computation providers, built-in, reference] --- - -# Built-in Computation Providers +## Built-In Computation Providers Reference SolidX ships with the following computation providers for common patterns. To use any of them, set `computedFieldValueProvider` to the provider name and pass the required context as a JSON string in `computedFieldValueProviderCtxt`. @@ -18,10 +17,7 @@ For background on how computation providers work, see [Computation Providers](.. Generates a random **alphanumeric code** with an optional prefix and configurable length. Useful for invoice numbers, record codes, or any short human-readable identifier. -
- - Context interface - +### Context Interface ```ts export interface AlphaNumExternalIdContext { @@ -37,12 +33,7 @@ export interface AlphaNumExternalIdContext { | `length` | `number` | `5` | `6` | Length of the generated alphanumeric portion | | `dynamicFieldPrefix` | `string` | - | `"clientCode"` | Field name on the entity to use as a dynamic prefix | -
- -
- - Example: generating an invoice number - +### Example: generating an invoice number **Use case:** When a new invoice is created, a unique human-readable invoice number is needed for display and reference. This example generates a code like `INV-A3X9K2` - an `"INV"` prefix followed by 6 random alphanumeric characters - so every invoice gets a distinct, easily shareable identifier automatically on insert. @@ -71,18 +62,13 @@ export interface AlphaNumExternalIdContext { { "invoiceNumber": "INV-A3X9K2" } ``` -
- --- ## ConcatEntityComputedFieldProvider Concatenates **one or more fields** on the entity into a single string. Supports 1-level-deep relation paths (e.g., `"city.name"`) and optional slugification. -
- - Context interface - +### Context Interface ```ts export interface ConcatComputedFieldContext { @@ -98,12 +84,7 @@ export interface ConcatComputedFieldContext { | `separator` | `string` | - | `" "` | String placed between each field value | | `slugify` | `boolean` | `false` | `true` | If `true`, slugifies each field value before concatenating | -
- -
- - Example: full name from first and last name - +### Example: full name from first and last name **Use case:** A student record stores first and last name as separate fields, but the UI and search require a single `fullName` field. This example concatenates `firstName` and `lastName` with a space separator, producing a value like `"Jane Doe"` automatically on every insert or update - no manual assignment needed. @@ -133,12 +114,7 @@ export interface ConcatComputedFieldContext { { "fullName": "Jane Doe" } ``` -
- -
- - Example: slugified location code - +### Example: slugified location code **Use case:** A location record has `city` and `state` fields. A URL-safe slug is needed for routing or filtering - for example, `"new-york-ny"` instead of `"New York NY"`. Enabling `slugify` lowercases and hyphenates each value before concatenation, making the output safe to embed in URLs or use as a unique code. @@ -159,18 +135,13 @@ export interface ConcatComputedFieldContext { { "locationCode": "new-york-ny" } ``` -
- --- ## UuidExternalIdEntityComputedFieldProvider Generates a **UUID** with an optional static prefix. Suitable for entities that need globally unique references - especially across distributed systems. -
- - Context interface - +### Context Interface ```ts export interface UuidExternalIdContext { @@ -182,12 +153,7 @@ export interface UuidExternalIdContext { |---|---|---|---|---| | `prefix` | `string` | `""` | `"ORD"` | Static string prepended to the UUID (alias: `staticPrefix`) | -
- -
- - Example: order external ID - +### Example: order external ID **Use case:** Orders are referenced across multiple systems - billing, fulfilment, and support. A globally unique, prefixed ID like `ORD-550e8400-e29b-41d4-a716-446655440000` ensures each order can be unambiguously identified regardless of which system is querying it. The prefix makes the entity type immediately recognisable from the ID alone, which is useful in logs and cross-system communication. @@ -216,8 +182,6 @@ export interface UuidExternalIdContext { { "externalId": "ORD-550e8400-e29b-41d4-a716-446655440000" } ``` -
- --- ## NoopsEntityComputedFieldProviderService @@ -228,10 +192,7 @@ A **no-op provider** - it runs but does not modify the field value. Use it to ta This is useful when one provider handles several related computed fields in a single pass. Tag the secondary computed fields with NoopsEntityComputedFieldProviderService so they don't trigger redundant or conflicting logic independently. -
- - Example: multi-field amount computation - +### Example: multi-field amount computation **Use case:** An invoice has three computed financial fields: `amount`, `taxes`, and `totalAmount`. A single custom provider - `CalculateTotalsProvider` - computes all three values in one pass when `totalAmount` is triggered. Because `CalculateTotalsProvider` writes the `taxes` value as part of that same computation, there is no need for a separate provider to recalculate it. @@ -257,5 +218,3 @@ To handle this, `taxes` is tagged with `NoopsEntityComputedFieldProviderService` ``` The `taxes` value is written by `CalculateTotalsProvider` when it processes `totalAmount`. Assigning `NoopsEntityComputedFieldProviderService` here ensures the field is correctly typed as computed without triggering any additional - and potentially conflicting - calculation of its own. - -
diff --git a/content/docs/developer-docs/extending/reference/built-in-selection-providers.mdx b/content/docs/developer-docs/extending/reference/built-in-selection-providers.mdx index f7fdcfa..4cb2ee5 100644 --- a/content/docs/developer-docs/extending/reference/built-in-selection-providers.mdx +++ b/content/docs/developer-docs/extending/reference/built-in-selection-providers.mdx @@ -1,15 +1,14 @@ --- title: Built-in Selection Providers icon: "list-filter" -description: Learn about the built-in selection providers available in SolidX - ListOfValuesSelectionProvider and PseudoForeignKeySelectionProvider. +description: Reference for the built-in selection providers available in SolidX, including `ListOfValuesSelectionProvider` and `PseudoForeignKeySelectionProvider`. summary: Documents the two built-in dynamic selection providers shipped with SolidX. ListOfValuesSelectionProvider populates dropdowns from List of Values (LOV) metadata entries filtered by type, while PseudoForeignKeySelectionProvider fetches options from any existing model to create lightweight foreign-key-style relationships without a formal database relation. Covers context configuration, field metadata examples, and search/query behaviour for both providers. keywords: [backend, dynamic selection, providers, built-in, list of values, pseudo foreign key] solidx_concerns: [backend.custom_dynamic_selection_providers, dynamic_selection_provider] --- - -# Built-in Selection Providers +## Built-In Selection Providers SolidX ships with two built-in dynamic selection providers so you can wire up common dropdown patterns without writing any code. If you need something more advanced, see [Dynamic Selection Providers](../backend-customization/dynamic-selection-providers) for creating your own. @@ -19,8 +18,6 @@ If you need something more advanced, see [Dynamic Selection Providers](../backen | `ListOfValuesSelectionProvider` | Populate a dropdown from [List of Values](../../metadata_schema/list-of-values.md) metadata entries | | `PseudoForeignKeySelectionProvider` | Populate a dropdown from records in **any existing model**, creating a lightweight foreign-key-style relationship without a formal database relation | ---- - ## ListOfValuesSelectionProvider Use this provider when the options for a field come from your **List of Values** metadata. @@ -37,10 +34,7 @@ The context object passed via `selectionDynamicProviderCtxt` accepts: ### Field Metadata Example
- - - Example: Dynamic selection field using ListOfValuesSelectionProvider - + Example: Dynamic selection field using ListOfValuesSelectionProvider ```json { @@ -70,28 +64,38 @@ The context object passed via `selectionDynamicProviderCtxt` accepts: ### How It Works -1. SolidX reads the `selectionDynamicProviderCtxt` and extracts the `type` value. -2. The provider queries the internal `ListOfValuesService` with a filter of `type = `. -3. If the user types a search query in the dropdown, the provider additionally filters by `display` (case-insensitive contains). -4. Each matching LOV record is mapped to `{ label: record.display, value: record.value }` and returned to the UI. - - - The LOV entries themselves are defined in your module's metadata file under the key listOfValues key. See the List of Values metadata schema for details on how to define them. -
+ + + SolidX reads the `selectionDynamicProviderCtxt` and extracts the `type` value. + + + The provider queries the internal `ListOfValuesService` with a filter of `type = `. + + + If the user types a search query in the dropdown, the provider additionally filters by `display`, using case-insensitive contains. + + + Each matching LOV record is mapped to `{ label: record.display, value: record.value }` and returned to the UI. + + + + + The LOV entries themselves are defined in your module's metadata file under the listOfValues key. See the List of Values metadata schema for details on how to define them. + You can also refer to Configuring List of Values for instructions on how to manage LOV entries via the admin UI. + ---- - ## PseudoForeignKeySelectionProvider Use this provider when you want a dropdown whose options come from **records in another model** - without creating a formal database foreign key relationship. This is useful for loosely-coupled references where a full relation is overkill or the models live in different modules. + + Use PseudoForeignKeySelectionProvider when you need to link data from a co-model, or any other model, to your current model but you cannot or do not want to create an actual database relation between them. - Use PseudoForeignKeySelectionProvider when you need to link data from a co-model (or any other model) to your current model but you cannot or don't want to create an actual database relation between them. -
- Example scenario: Suppose you have a customer model in one module and a country model in another. You want the user to pick a country when creating a customer, but you don't want a formal foreign key - perhaps because the models are managed by different teams, the country data is reference-only, or you simply want to store the country code as a plain string rather than enforce referential integrity. With this provider you can populate a dynamic dropdown from the country model's records while keeping the two models completely decoupled at the database level. + Example scenario: Suppose you have a customer model in one module and a country model in another. You want the user to pick a country when creating a customer, but you do not want a formal foreign key. With this provider, you can populate a dynamic dropdown from the country model's records while keeping the two models completely decoupled at the database level. +
### Context @@ -105,17 +109,15 @@ The context object passed via `selectionDynamicProviderCtxt` accepts: | `valueFieldName` | `string` | Yes | The field on the target model to use as the **stored value** | | `whereClauseFields` | `string[]` | Yes | Fields on the target model to search against when the user types a query | - + The provider also respects the standard limit and offset context properties for pagination. + ### Field Metadata Example
- - - Example: Dynamic selection field using PseudoForeignKeySelectionProvider - + Example: Dynamic selection field using PseudoForeignKeySelectionProvider ```json { @@ -145,13 +147,23 @@ The context object passed via `selectionDynamicProviderCtxt` accepts: ### How It Works -1. SolidX reads the `selectionDynamicProviderCtxt` and extracts `modelName`, `labelFieldName`, `valueFieldName`, and `whereClauseFields`. -2. The provider uses `SolidIntrospectService` to look up the CRUD service for the specified model at runtime. -3. If the user types a search query, the provider builds an `$or` filter across all `whereClauseFields` using case-insensitive contains (`$containsi`). -4. The matching records are mapped to `{ label: record[labelFieldName], value: record[valueFieldName] }` and returned to the UI. + + + SolidX reads the `selectionDynamicProviderCtxt` and extracts `modelName`, `labelFieldName`, `valueFieldName`, and `whereClauseFields`. + + + The provider uses `SolidIntrospectService` to look up the CRUD service for the specified model at runtime. + + + If the user types a search query, the provider builds an `$or` filter across all `whereClauseFields` using case-insensitive contains, `\$containsi`. + + + The matching records are mapped to `{ label: record[labelFieldName], value: record[valueFieldName] }` and returned to the UI. + + - Use **`ListOfValuesSelectionProvider`** when your options are a fixed, admin-managed set defined in metadata (e.g. statuses, categories, industries). -- Use **`PseudoForeignKeySelectionProvider`** when your options come from **live records** in another model (e.g. countries, clients, products). -- If neither fits, [create a custom dynamic selection provider](../backend-customization/dynamic-selection-providers). + - Use **`PseudoForeignKeySelectionProvider`** when your options come from **live records** in another model (e.g. countries, clients, products). + - If neither fits, [create a custom dynamic selection provider](../backend-customization/dynamic-selection-providers). diff --git a/content/docs/developer-docs/extending/reference/index.md b/content/docs/developer-docs/extending/reference/index.mdx similarity index 95% rename from content/docs/developer-docs/extending/reference/index.md rename to content/docs/developer-docs/extending/reference/index.mdx index bf2a4c6..ab97733 100644 --- a/content/docs/developer-docs/extending/reference/index.md +++ b/content/docs/developer-docs/extending/reference/index.mdx @@ -4,7 +4,7 @@ icon: "book-open" description: Reference documentation for built-in providers and extension points in SolidX. --- -# Reference +## Built-In Reference Reference for built-in providers available in SolidX. These are ready-to-use implementations you can wire up via metadata configuration - no custom code required. diff --git a/content/docs/developer-docs/index.mdx b/content/docs/developer-docs/index.mdx index 210636e..7d55d3d 100644 --- a/content/docs/developer-docs/index.mdx +++ b/content/docs/developer-docs/index.mdx @@ -1,30 +1,66 @@ --- title: Reference icon: "code-2" -description: Comprehensive documentation for SolidX developers. -summary: Welcome to SolidX developer documentation. SolidX is an enterprise-focused, low-code development platform engineered for modern web applications, providing comprehensive tools for rapid application development with full customization capabilities. +description: Reference pages covering project structure, metadata, APIs, extension points, testing, and deployment in SolidX. +summary: Technical reference for how a SolidX application is bootstrapped, structured, generated, extended, tested, and deployed. --- -# Developer Docs +## Developer Docs -Welcome to SolidX admin documentation! SolidX is an enterprise-focused, low-code development platform engineered for today's web applications. +Welcome to SolidX developer documentation. SolidX is an enterprise-focused, metadata-driven application platform engineered for modern web applications. - + - The Reference section is best read as a map of the different layers of a SolidX project. - - Setup: prerequisites, installation, and project structure - - Operations: CLI usage, seeding, testing, and deployment - - Platform definition: metadata schema and generated behaviour - - Interfaces: REST APIs and frontend/backend extension points - So the intuition is: this section is not just a pile of isolated docs pages. It is a reference map for how a SolidX application is built, configured, extended, and operated. +The Reference section is best read as a map of the major layers inside a SolidX project. +- `Setup`: prerequisites, installation, and project structure +- `Operations`: CLI workflows, seeding, testing, and deployment +- `Platform definition`: metadata schema and generated behaviour +- `Interfaces`: REST APIs and frontend/backend extension points + +This section serves as a technical reference map for how a SolidX application is bootstrapped, configured, generated, extended, and operated. -This section includes: +## Project Foundations + +Core references for bootstrapping a SolidX workspace and understanding how the project is organized. + + + + Establish the local toolchain required for SolidX development, including Node.js, PostgreSQL, Git, Python-based MCP/agent prerequisites, and supporting CLI utilities. + + + Bootstrap a new SolidX workspace with `solidctl create-app` and understand the initialization flow before moving into application-level work. + + + Review how `solid-api`, `solid-ui`, metadata, generated artifacts, and shared SolidX packages fit together within the application workspace. + + + Use the CLI as the operational control surface for project creation, build, seeding, generation, upgrades, testing, and platform maintenance. + + + +## SolidX Platform Reference Areas + +Reference pages covering metadata, REST APIs, extension points, dashboards, testing, and production deployment. -- setup and installation guidance, -- project structure and CLI reference, -- metadata schema reference, -- testing architecture and automation workflow, -- REST API reference, -- and extension/customization guides. + + + Work with the metadata schema that defines models, fields, views, actions, menus, permissions, templates, and other generated platform behavior. + + + Extend the generated system through supported backend and frontend customization points rather than forking or bypassing framework conventions. + + + Review authentication, CRUD conventions, recovery semantics, and Swagger-backed API behavior across generated resources. + + + Build metadata-driven dashboards, widget providers, and runtime-backed operational reporting surfaces. + + + Work with the metadata-driven testing system, including scenario authoring, API automation, UI automation, and test workflow orchestration. + + + Prepare SolidX for production deployment across Docker, ECS, and VM-based hosting models with the associated operational considerations. + + diff --git a/content/docs/developer-docs/installation.mdx b/content/docs/developer-docs/installation.mdx index c089fa0..8472f63 100644 --- a/content/docs/developer-docs/installation.mdx +++ b/content/docs/developer-docs/installation.mdx @@ -1,36 +1,49 @@ --- title: Installation icon: "download" -description: Overview of how to initialize a SolidX project with links to the full step-by-step tutorial. -summary: This document provides a quick overview of installing SolidX using `solidctl create-app`. It explains the installation flow at a high level, then shows the command used to scaffold a new project containing both `solid-api` and `solid-ui`, along with a link to a full guided tutorial. +description: Overview of how to initialize a SolidX project with `solidctl create-app`, with links to the full step-by-step tutorial. +summary: Explains how `solidctl create-app` initializes a SolidX workspace and links to the current setup guides. --- -# Installing SolidX +## Project Bootstrap -Installing `SolidX` is a breeze with our [`solidctl create-app`](https://www.npmjs.com/package/@solidxai/solidctl) workflow. +SolidX installation starts by bootstrapping a new project with [`solidctl create-app`](https://www.npmjs.com/package/@solidxai/solidctl). - Installing SolidX is really a project bootstrap step, not just a package installation step. - - create-app scaffolds a new SolidX application workspace. - - That workspace includes both solid-api and solid-ui. - - You then build the project, seed metadata, and start development from there. - So the intuition is: you are creating a working SolidX project skeleton, not merely adding a dependency to an existing folder. +Installing SolidX is a project bootstrap step, not a library-install step. + +- `create-app` scaffolds a complete SolidX application workspace. +- That workspace contains both `solid-api` and `solid-ui`. +- You then build the project, seed metadata, and continue into development from there. + +The key point is that SolidX creates a working project skeleton, not just a dependency added to an existing folder. -## Quick Overview -- Run the command below to initialize your SolidX project: +## Bootstrap Flow + +Run the command below to initialize your SolidX project: - ```bash - solidctl create-app - ``` +```bash +solidctl create-app +``` -- Answer a few simple prompts to configure your project. -- This scaffolds a new project with both backend and frontend applications. -- After scaffolding, the usual next steps are to build the project and seed metadata. -- Customize SolidX to fit your needs! + + + Run `solidctl create-app` and supply the required project, database, and runtime configuration values. + + + The command scaffolds both `solid-api` backend and `solid-ui` frontend inside a single SolidX workspace. + + + After scaffolding, start the generated project, validate the admin UI and API surfaces, and then move into application-specific modeling and extension work. + + + +## Step-By-Step Tutorial -## Step-by-Step Tutorial For complete step-by-step installation guidance, including environment setup and configuration, follow the dedicated tutorial: -- [Bootstrap SolidX for School Fees Portal](/docs/tutorial/school-fees-portal/index.md) + +- [Quick Start](/docs/quick-start) +- [Todo App with SolidX](/docs/tutorial/todo-app) diff --git a/content/docs/developer-docs/metadata_schema/action-metadata.mdx b/content/docs/developer-docs/metadata_schema/action-metadata.mdx index eaa0c2c..ba22853 100644 --- a/content/docs/developer-docs/metadata_schema/action-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/action-metadata.mdx @@ -2,7 +2,7 @@ title: Actions icon: "zap" description: Metadata schema for defining actions in SolidX applications. -summary: This document defines action metadata in SolidX, which determines what happens when users interact with UI elements like menu items, buttons, or links. Actions connect the frontend to backend functionality and control how data is displayed or processed. The metadata supports two main action types - solid (standard SolidX actions linked to views) and custom (custom component actions with optional modal display). Key attributes include action name, display name, type, domain, context, custom component path, server endpoint, associated view, module, and model. Actions serve as the bridge between user interactions and application responses. +summary: Covers the metadata used to define SolidX actions, including built-in actions, custom actions, view linkage, routing, and modal behavior. json_pointer: "/actions" jsonpath: "$.actions" parent_component: root @@ -12,8 +12,6 @@ items_attributes_doc: "#action-metadata-attributes" solidx_concerns: [add_custom_menu_action_combo] --- - -# Action Metadata **JSON Pointer:** `/actions` @@ -23,39 +21,42 @@ solidx_concerns: [add_custom_menu_action_combo] ## Overview -Actions define what happens when users interact with UI elements like menu items, buttons, or links. They connect the frontend to backend functionality and determine how data is displayed or processed. +Action metadata defines what happens when a user interacts with a menu item, button, or other clickable UI element in a SolidX application. -Menus, buttons, and links in SolidX applications are associated with actions. +Menus, buttons, and links resolve to actions. An action is therefore the binding layer between a user interaction and the runtime surface that should open or execute. -When a user clicks on one of these UI elements, the corresponding action is triggered, executing the defined behavior. +When a user clicks one of these UI elements, the corresponding action is triggered and the defined behavior is executed. -Key Configuration Points: +### Key Configuration Points -1. **Module and View Association**: All actions need to be linked to a module and a view. +1. **Module and view association** +All actions belong to a module. When the action opens a generated SolidX view, it should also reference the relevant `viewUserKey`, and in most cases the matching `modelUserKey`. -2. **Solid Actions**: In case of solid actions, the view user key and model user key is required. Since solid actions are generally linked to standard SolidX views, no custom component path is needed. In case of custom actions, a custom component path i.e (the linked view) is required. +2. **`solid` actions** +Use `solid` actions when the target is a generated SolidX view. In this case, `viewUserKey` and `modelUserKey` are the main linkage fields, and `customComponent` is not needed. -3. **Custom Actions**: Custom actions can optionally be displayed as modal dialogs. If the action is a custom action, the `customComponent` attribute must be provided to specify the path to the custom frontend component. The `customIsModal` attribute indicates if the component should be displayed as a modal dialog. +3. **`custom` actions** +Use `custom` actions when the target is a custom frontend surface rather than a generated view. In this case, `customComponent` is required, and `customIsModal` controls whether that component is shown as a modal dialog. -In case a custom action is not associated with a model, the model user key can be left blank. +If a custom action is not associated with a model, `modelUserKey` can be left empty. ### Action Types -1. **Solid Actions**: Standard CRUD operations using SolidX's built-in views -2. **Custom Actions**: Custom components or pages with specific functionality +1. **`solid` actions**: +Use `solid` actions for standard SolidX views such as list, form, tree, card, or kanban views. + +2. **`custom` actions**: +Use `custom` actions when the target is a custom frontend component or page rather than a generated SolidX view. ### Configuration Examples ### `Solid` Action Example -Below is an example of a `solid` action configuration, which links to a standard SolidX view for listing institutes. +Below is a `solid` action that opens a generated institute list view.
- - - Click to expand - +Solid action example ```json { ..., // Other metadata @@ -80,12 +81,9 @@ Below is an example of a `solid` action configuration, which links to a standard
### `Custom` Action Example -Below is an example of a `custom` action configuration, which links to a custom frontend component for the fees portal home page. +Below is a `custom` action that routes into a custom frontend surface for the fees portal home page.
- - - Click to expand - +Custom action example ```json { ..., // Other metadata @@ -111,12 +109,9 @@ Below is an example of a `custom` action configuration, which links to a custom ## Complete Navigation Structure Example -Here's a complete navigation structure example from the fees-portal, illustrating how menus and actions are defined together: +This example shows how menu items and actions are authored together inside one module:
- - - Click to expand - +Navigation structure example ```json { @@ -161,10 +156,7 @@ Here's a complete navigation structure example from the fees-portal, illustratin ```
-

- -## Action Metadata Atributes -

+## Action Metadata Attributes ### `name` *(string, required, unique)* @@ -181,8 +173,8 @@ Display name of the action item (shown in the UI). ### `type` *(string, required)* Type of action. Supported types: -- `solid`: Standard SolidX action that interacts with SolidX backend services. -- `custom`: Custom action that uses a custom frontend component. You need to provide the `customComponent` attribute for this type. +- `solid`: Opens or resolves to a generated SolidX view. +- `custom`: Custom action that uses a custom frontend component. Provide `customComponent` for this type. **Default:** N/A @@ -190,8 +182,7 @@ Type of action. Supported types: ### `domain` *(JSON, optional)* JSON object defining domain-specific parameters for the action. **Default:** N/A - ---- + ### `context` *(JSON, optional)* JSON object defining context-specific parameters for the action. @@ -230,10 +221,6 @@ User key of the module this action belongs to. **Default:** N/A -### `modelUserKey` *(string, required)* -User key of the model this action operates on. +### `modelUserKey` *(string, optional)* +User key of the model this action operates on. This is typically present for `solid` actions and may be empty for custom actions that are not model-bound. **Default:** N/A - - - - diff --git a/content/docs/developer-docs/metadata_schema/email-templates.mdx b/content/docs/developer-docs/metadata_schema/email-templates.mdx index 55b9521..5f41192 100644 --- a/content/docs/developer-docs/metadata_schema/email-templates.mdx +++ b/content/docs/developer-docs/metadata_schema/email-templates.mdx @@ -2,7 +2,7 @@ title: Email icon: "mail" description: Metadata schema for populating email templates in SolidX applications. -summary: This document explains email template metadata in SolidX, which enables creation and management of HTML/text-based email templates with dynamic content and attachments. Templates use Handlebars syntax for variable insertion and are stored in separate HTML files referenced by the metadata. Key attributes include template name, display name, body file reference, subject line, description, active status, and template type (text/html). Examples demonstrate configuring templates for payment reminders and OTP verification, including sample HTML template files with dynamic variables, styling, and layout structures. The system supports template file organization in the solid-api/src directory. +summary: Covers the metadata used to define email templates in SolidX, including body-file references, subject lines, activation flags, and template types. json_pointer: "/emailTemplates" jsonpath: "$.emailTemplates" parent_component: root @@ -12,7 +12,6 @@ items_attributes_doc: "#email-templates-metadata-attributes" solidx_concerns: [create/update_email_template, new_email_provider] --- -# Email Templates **JSON Pointer:** `/emailTemplates` @@ -22,10 +21,12 @@ solidx_concerns: [create/update_email_template, new_email_provider] ## Overview -Email Templates in `SolidX` allow you to create and manage HTML/Text based email templates with dynamic content and attachments. +Email templates in SolidX let you define and manage HTML or plain-text email templates used by the platform. Each template record includes the template name, display name, body file, subject line, activation state, and template type. + +The body content is stored in a separate template file referenced by the `body` field. These files can include Handlebars placeholders so runtime data can be injected when the email is sent. ### Example: Email Templates Metadata -Below is an example configuration for two email templates: one for sending payment reminders and another for OTP verification. The body of the email templates is stored in separate HTML files i.e (specified in the `body` attribute) +This example defines two email templates: one for payment reminders and one for OTP verification. In both cases, the `body` field points to a separate template file.
Email Templates Schema @@ -57,7 +58,7 @@ Below is an example configuration for two email templates: one for sending payme ```
-### Example : Email Template File +### Example: Email Template File Below are examples of email template files that can be referenced in the `body` attribute of the email template metadata. @@ -166,7 +167,7 @@ The variables used in this template (like `{{student.studentName}}`, `{{dueDetai ```
- Email Template File (Text) + Text email template example ```tsx Hi {{ fullName }}, @@ -187,7 +188,7 @@ The {{ solidAppName }} Team ```
-### Example : Sending Email Using Template +### Example: Sending Email Using a Template Below is a code snippet demonstrating how to send an email using the defined email templates via the `MailServiceFactory`. This example shows how to send an OTP verification email to a user. @@ -237,11 +238,14 @@ Unique name for the email template. It should be in kebab-case format (e.g., `ex Display name for the email template. ### `body` *(string, required)* - - In the metadata json, the filename of the email template is specified. The templates are searched for in the `module-metadata//email-templates/` directory of the module. - - The body is then replaced with the content of the email template file. This can include HTML or plain text content. The body can include dynamic placeholders using Handlebars syntax (e.g., `{{placeholderName}}`), as shown in the [Email Template file](#example--email-template-file) above. -#### Further Reference - - **Email Body Creation:** [Email Templates Guide](../../admin-docs/notifications/email-templates.md) +- In metadata JSON, `body` holds the template filename. +- SolidX resolves that file from `module-metadata//email-templates/`. +- The file content can be HTML or plain text and can include Handlebars placeholders such as `{{placeholderName}}`. + +#### Further Reference + +- **Email Body Creation:** [Email Templates Guide](../../admin-docs/notifications/email-templates.md) Please refer to the [Handlebars Documentation](https://handlebarsjs.com/) for more information on using Handlebars syntax in email templates. diff --git a/content/docs/developer-docs/metadata_schema/field-metadata.mdx b/content/docs/developer-docs/metadata_schema/field-metadata.mdx index 33035de..d8bad64 100644 --- a/content/docs/developer-docs/metadata_schema/field-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/field-metadata.mdx @@ -6,13 +6,12 @@ summary: Field metadata defines the semantic contract of each model field in Sol json_pointer: "/moduleMetadata/models/fields" jsonpath: "$.moduleMetadata.models[*].fields[*]" parent_component: models -type: array, +type: array items_type: "object" items_attributes_doc: "#field-metadata-attributes" solidx_concerns: [add_field_to_a_model, remove_field_from_a_model, create_model_with_fields] --- -# Field Metadata **JSON Pointer:** `/moduleMetadata/models/fields` @@ -121,12 +120,12 @@ Attrs such as `ormType`, `columnName`, `unique`, and `index` are therefore best Because `shortText` is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including: -- equality and inequality +- Equality and inequality - `in` and `notIn` - `contains` and `notContains` -- case-insensitive contains variants +- Case-insensitive contains variants - `startsWith` and `endsWith` -- null and not-null checks +- Null and not-null checks This makes `shortText` a natural fit for searchable list views, user keys, codes, names, and other text-oriented query flows. @@ -214,7 +213,7 @@ For `longText`, SolidX validates in two places: Two important behaviors to note: - `min` and `max` are enforced in generated form validation -- backend validation does not currently enforce `min` or `max` for `longText` +- Backend validation does not currently enforce `min` or `max` for `longText` @@ -230,12 +229,12 @@ Attrs such as `ormType`, `columnName`, `unique`, and `index` are therefore best Because `longText` is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including: -- equality and inequality +- Equality and inequality - `in` and `notIn` - `contains` and `notContains` -- case-insensitive contains variants +- Case-insensitive contains variants - `startsWith` and `endsWith` -- null and not-null checks +- Null and not-null checks This makes `longText` suitable for description-style filters, notes, instructions, and text-driven administrative search flows. @@ -320,7 +319,7 @@ For `richText`, SolidX validates in two places: Two important behaviors to note: - `min` and `max` are enforced in generated form validation -- backend validation does not currently enforce `min` or `max` for `richText` +- Backend validation does not currently enforce `min` or `max` for `richText` @@ -336,12 +335,12 @@ Attrs such as `ormType`, `columnName`, `unique`, and `index` are therefore best Because `richText` is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including: -- equality and inequality +- Equality and inequality - `in` and `notIn` - `contains` and `notContains` -- case-insensitive contains variants +- Case-insensitive contains variants - `startsWith` and `endsWith` -- null and not-null checks +- Null and not-null checks This makes `richText` suitable for administrative search and text-driven query flows, even though end-user presentation is usually richer than plain text. @@ -416,7 +415,7 @@ For `json`, SolidX validates in two places: One important behavior to note: -- unlike text-based field types, the backend validator explicitly checks whether the submitted value is valid JSON rather than only checking its scalar type +- Unlike text-based field types, the backend validator explicitly checks whether the submitted value is valid JSON rather than only checking its scalar type @@ -524,9 +523,9 @@ Because `int` represents a numeric scalar, it works naturally with numeric sorti Typical use cases include: -- sorting records by sequence or rank -- filtering by counts and operational thresholds -- reporting on durations, quantities, or other whole-number metrics +- Sorting records by sequence or rank +- Filtering by counts and operational thresholds +- Reporting on durations, quantities, or other whole-number metrics In practice, `int` is the natural choice when business meaning depends on numeric ordering rather than on text search. @@ -602,8 +601,8 @@ For `bigint`, SolidX validates requiredness and numeric shape at the CRUD bounda Two important behaviors to note: -- backend validation accepts string or number inputs and coerces them into a bigint-aware value before applying the numeric checks -- the generated UI currently reuses the integer field path, so very large values should be reviewed carefully when they may exceed JavaScript safe-integer handling +- Backend validation accepts string or number inputs and coerces them into a bigint-aware value before applying the numeric checks +- The generated UI currently reuses the integer field path, so very large values should be reviewed carefully when they may exceed JavaScript safe-integer handling @@ -621,9 +620,9 @@ Because `bigint` remains a numeric scalar, it fits the same broad query patterns Typical use cases include: -- sorting by imported numeric identifiers -- exact lookup by large request or transaction keys -- operational reporting on large-duration counters and legacy numeric values +- Sorting by imported numeric identifiers +- Exact lookup by large request or transaction keys +- Operational reporting on large-duration counters and legacy numeric values In practice, `bigint` is most useful where whole-number semantics matter but ordinary integer assumptions are too small or too implementation-specific. @@ -722,9 +721,9 @@ Because `decimal` represents a numeric scalar, it works naturally with sorting, Typical use cases include: -- filtering records by amount thresholds -- sorting balances, prices, or rates -- reporting on numeric values where fractional precision matters +- Filtering records by amount thresholds +- Sorting balances, prices, or rates +- Reporting on numeric values where fractional precision matters In practice, `decimal` is the natural choice whenever business meaning depends on numeric precision rather than on textual formatting. @@ -801,7 +800,7 @@ For `boolean`, SolidX validates in two places: Two important behaviors to note: - `boolean` does not use text-oriented attrs such as `min`, `max`, `length`, or `regexPattern` -- at the CRUD boundary, the runtime value is treated as a true-or-false field rather than as free-form text +- At the CRUD boundary, the runtime value is treated as a true-or-false field rather than as free-form text @@ -819,9 +818,9 @@ Because `boolean` represents a binary state, it is most useful in exact-match st Typical use cases include: -- filtering records by enabled versus disabled state -- separating approved and unapproved records -- narrowing operational queues by simple flags such as duplicate, active, verified, or system-owned +- Filtering records by enabled versus disabled state +- Separating approved and unapproved records +- Narrowing operational queues by simple flags such as duplicate, active, verified, or system-owned In practice, `boolean` fits best where users need to quickly slice a dataset by state rather than search inside a textual value. @@ -899,7 +898,7 @@ For `date`, SolidX validates in two places: Two important behaviors to note: - `date` does not use text-oriented attrs such as `min`, `max`, `length`, or `regexPattern` -- the same CRUD validation path is also reused for `datetime`, so date-like fields share a common backend date-validation contract +- The same CRUD validation path is also reused for `datetime`, so date-like fields share a common backend date-validation contract @@ -917,9 +916,9 @@ Because `date` represents a calendar value, it is well suited to time-oriented f Typical use cases include: -- sorting records by chronology -- filtering records by a specific day -- narrowing datasets by effective date, approval date, or joining date +- Sorting records by chronology +- Filtering records by a specific day +- Narrowing datasets by effective date, approval date, or joining date In practice, `date` works best where users need consistent calendar semantics rather than free-form text search. @@ -997,7 +996,7 @@ For `datetime`, SolidX validates in two places: Two important behaviors to note: - `datetime` does not use text-oriented attrs such as `min`, `max`, `length`, or `regexPattern` -- the same CRUD validation path is currently shared with `date`, so both field types rely on the same backend date-validation contract +- The same CRUD validation path is currently shared with `date`, so both field types rely on the same backend date-validation contract @@ -1015,9 +1014,9 @@ Because `datetime` represents a timestamp-like value, it is well suited to chron Typical use cases include: -- ordering records by event time -- filtering by publication, approval, or execution time -- presenting audit-style timelines and process timestamps +- Ordering records by event time +- Filtering by publication, approval, or execution time +- Presenting audit-style timelines and process timestamps In practice, `datetime` is the natural choice whenever time-of-day matters as much as the date itself. @@ -1091,7 +1090,7 @@ For `time`, SolidX currently validates requiredness in the generated form layer One important behavior to note: -- core UI support for `time` is present, but `crud.service.ts` does not currently route `SolidFieldType.time` through a dedicated backend field manager, so the backend runtime contract is not yet as complete as the contracts for `date` and `datetime` +- Core UI support for `time` is present, but `crud.service.ts` does not currently route `SolidFieldType.time` through a dedicated backend field manager, so the backend runtime contract is not yet as complete as the contracts for `date` and `datetime` @@ -1109,9 +1108,9 @@ Because `time` represents a clock-time value, it is most useful for schedule-sty Typical use cases include: -- start and end times for scheduled jobs -- opening and closing times -- time-only display in generated forms and reports +- Start and end times for scheduled jobs +- Opening and closing times +- Time-only display in generated forms and reports In practice, `time` is best used where the UI experience is valuable today and the backend behavior is known and reviewed as part of implementation. @@ -1190,8 +1189,8 @@ For `email`, SolidX validates in two places: Three important behaviors to note: -- backend validation uses an email-aware validator even when no custom regex is authored -- generated form validation relies on `regexPattern` when stricter email-format checks are needed +- Backend validation uses an email-aware validator even when no custom regex is authored +- Generated form validation relies on `regexPattern` when stricter email-format checks are needed - `max` defaults to the email-safe core limit when it is not authored explicitly @@ -1210,9 +1209,9 @@ Because `email` is a scalar textual field, it works naturally with the standard Typical use cases include: -- exact lookup by email address -- partial search in operational lists -- identifying records by a stable contact identifier +- Exact lookup by email address +- Partial search in operational lists +- Identifying records by a stable contact identifier In practice, `email` combines the searchability of text with stronger validation expectations than a generic short string. @@ -1293,9 +1292,9 @@ For `password`, SolidX validates in two places: Three important behaviors to note: -- backend requiredness is applied on create rather than on ordinary update flows -- password confirmation is treated as part of the contract when a password value is supplied -- when no custom regex is authored, the backend falls back to a strong-password default pattern +- Backend requiredness is applied on create rather than on ordinary update flows +- Password confirmation is treated as part of the contract when a password value is supplied +- When no custom regex is authored, the backend falls back to a strong-password default pattern @@ -1388,7 +1387,7 @@ Three important behaviors to note: - `selectionStaticValues` defines the allowed set using `value:label` entries, where the left-hand side is the stored value and the right-hand side is the display label - `selectionValueType` controls how the submitted value is interpreted at validation time -- when `isMultiSelect` is enabled, the backend accepts an array or a JSON-stringified array and validates each submitted value against the authored set +- When `isMultiSelect` is enabled, the backend accepts an array or a JSON-stringified array and validates each submitted value against the authored set @@ -1406,9 +1405,9 @@ Because `selectionStatic` stores a constrained set of known values, it is well s Typical use cases include: -- filtering by status, stage, type, or category -- segmenting records by workflow state -- narrowing records by authored option sets such as day of week, product type, or review outcome +- Filtering by status, stage, type, or category +- Segmenting records by workflow state +- Narrowing records by authored option sets such as day of week, product type, or review outcome In practice, `selectionStatic` is most valuable where consistency matters more than free-form input. @@ -1499,7 +1498,7 @@ Three important behaviors to note: - `selectionDynamicProvider` chooses the provider used to resolve valid options at runtime - `selectionDynamicProviderCtxt` is JSON-decoded before validation and can shape provider behavior -- when the provider context sets `validateOnSave` to `false`, save-time provider validation is skipped and only the value-type contract is enforced +- When the provider context sets `validateOnSave` to `false`, save-time provider validation is skipped and only the value-type contract is enforced @@ -1517,9 +1516,9 @@ Because `selectionDynamic` stores constrained provider-backed values, it is well Typical use cases include: -- choosing values from a list-of-values provider -- selecting records from a provider-backed business catalog -- narrowing workflows based on provider-defined state or category values +- Choosing values from a list-of-values provider +- Selecting records from a provider-backed business catalog +- Narrowing workflows based on provider-defined state or category values In practice, `selectionDynamic` is most useful when the option set must remain dynamic without giving up structured persistence. @@ -1603,9 +1602,9 @@ For `many-to-one`, SolidX validates in two places: Three important behaviors to note: -- the request contract accepts either an integer-style id or the related model's user key -- required validation fails only when both the id and the user key are absent -- if a user key is submitted, the related model must expose a user-key field that can be used for lookup +- The request contract accepts either an integer-style id or the related model's user key +- Required validation fails only when both the id and the user key are absent +- If a user key is submitted, the related model must expose a user-key field that can be used for lookup @@ -1623,9 +1622,9 @@ Because `many-to-one` points to a single related record, it is a natural fit for Typical use cases include: -- filtering child records by a parent entity such as institute, branch, or customer -- populating related records in form and list flows -- using the related model's user key as the display or search value in metadata-driven UI +- Filtering child records by a parent entity such as institute, branch, or customer +- Populating related records in form and list flows +- Using the related model's user key as the display or search value in metadata-driven UI In practice, `many-to-one` is the relation subtype most often used for simple lookup-style business relationships. @@ -1714,8 +1713,8 @@ For `one-to-many`, SolidX validates the relation using command-style mutation se The generated form layer validates requiredness and collection shape. The backend CRUD layer validates the command field and then expects one of two payload styles: -- for `create`, `update`, and `delete`, the payload is array-shaped and submitted through the relation value field itself -- for `set`, `link`, and `unlink`, the payload is submitted through `Ids` +- For `create`, `update`, and `delete`, the payload is array-shaped and submitted through the relation value field itself +- For `set`, `link`, and `unlink`, the payload is submitted through `Ids` Three important behaviors to note: @@ -1739,9 +1738,9 @@ This makes `one-to-many` more operationally expressive than scalar fields: it is Typical use cases include: -- rendering child rows inside embedded forms or detail pages -- loading child collections through relation-aware populate flows -- applying parent-scoped filters so that only the current record's children are shown or edited +- Rendering child rows inside embedded forms or detail pages +- Loading child collections through relation-aware populate flows +- Applying parent-scoped filters so that only the current record's children are shown or edited In practice, `one-to-many` works best when the relation is treated as a managed collection rather than as a list-search field. @@ -1831,13 +1830,13 @@ For `many-to-many`, SolidX validates the relation using the same command-style m The generated form layer validates requiredness and collection shape. The backend CRUD layer validates the command field, then expects one of two payload styles: -- for `create`, `update`, and `delete`, the payload is array-shaped and submitted through the relation value field itself -- for `set`, `link`, and `unlink`, the payload is submitted through `Ids` on the owner side, or through the resolved inverse field name on the inverse side +- For `create`, `update`, and `delete`, the payload is array-shaped and submitted through the relation value field itself +- For `set`, `link`, and `unlink`, the payload is submitted through `Ids` on the owner side, or through the resolved inverse field name on the inverse side Three important behaviors to note: - `Command` determines how the relation should be mutated -- owner-side versus inverse-side metadata affects which effective field names are used internally +- Owner-side versus inverse-side metadata affects which effective field names are used internally - `link` and `unlink` are update-only operations because they need an existing parent record id @@ -1856,9 +1855,9 @@ The owner-side flag matters here: it determines which side is responsible for th Typical use cases include: -- tagging records with multiple domains or categories -- assigning users, reviewers, or approvers to the same business record -- traversing relation membership through join-aware list and detail experiences +- Tagging records with multiple domains or categories +- Assigning users, reviewers, or approvers to the same business record +- Traversing relation membership through join-aware list and detail experiences In practice, `many-to-many` is best treated as a managed membership surface rather than as a scalar search field. @@ -1942,9 +1941,9 @@ For `mediaSingle`, SolidX validates the uploaded file collection in the backend Three important behaviors to note: -- on create, a required `mediaSingle` field must receive exactly one uploaded file -- if more than one file is submitted, validation fails because the field is single-valued -- when `mediaMaxSizeKb` or `mediaTypes` are authored, the backend validates the uploaded file against those constraints +- On create, a required `mediaSingle` field must receive exactly one uploaded file +- If more than one file is submitted, validation fails because the field is single-valued +- When `mediaMaxSizeKb` or `mediaTypes` are authored, the backend validates the uploaded file against those constraints On update, required validation is intentionally more permissive so that existing media can remain in place when no replacement file is uploaded. @@ -1964,9 +1963,9 @@ This makes `mediaSingle` a hybrid field contract: metadata is authored on the fi Typical use cases include: -- displaying a primary asset such as a logo or cover image in a list or form -- opening, previewing, or downloading the uploaded file in metadata-driven UI -- populating media payloads alongside the rest of the business record +- Displaying a primary asset such as a logo or cover image in a list or form +- Opening, previewing, or downloading the uploaded file in metadata-driven UI +- Populating media payloads alongside the rest of the business record In practice, media fields are usually queried for display and retrieval rather than for text- or number-style filtering. @@ -2044,8 +2043,8 @@ For `mediaMultiple`, SolidX validates requiredness in the backend CRUD layer. Two important behaviors to note: -- on create, a required `mediaMultiple` field must receive at least one uploaded file -- unlike `mediaSingle`, the current backend implementation does not yet apply the same file-type and file-size checks to every uploaded file in the collection +- On create, a required `mediaMultiple` field must receive at least one uploaded file +- Unlike `mediaSingle`, the current backend implementation does not yet apply the same file-type and file-size checks to every uploaded file in the collection That second behavior is important operationally: `mediaTypes` and `mediaMaxSizeKb` express the intended contract for the field, but collection-level enforcement is not yet as complete as it is for `mediaSingle`. @@ -2065,9 +2064,9 @@ This makes `mediaMultiple` a natural fit for document bundles, image sets, and a Typical use cases include: -- previewing the first item in the collection in list views -- opening the full media bundle in a dialog or lightbox-driven experience -- downloading document-style attachments from the record detail view +- Previewing the first item in the collection in list views +- Opening the full media bundle in a dialog or lightbox-driven experience +- Downloading document-style attachments from the record detail view In practice, media collections are queried for retrieval and presentation rather than for scalar-style filtering. @@ -2148,8 +2147,8 @@ For `computed`, SolidX does not apply ordinary end-user field validation. Two important behaviors to note: -- the backend computed-field flow does not apply ordinary user-input validation and therefore returns no direct field errors for submitted values -- generated forms treat the field as read-only and optional because the value is not expected to be provided by the user +- The backend computed-field flow does not apply ordinary user-input validation and therefore returns no direct field errors for submitted values +- Generated forms treat the field as read-only and optional because the value is not expected to be provided by the user This is by design: correctness comes from provider logic and trigger configuration rather than from normal user-input validation rules. @@ -2162,8 +2161,8 @@ In inline CRUD flows, SolidX parses `computedFieldValueProviderCtxt`, resolves t There are two cases where inline computation is intentionally skipped: -- partial updates -- fields that define `computedFieldTriggerConfig`, because those are expected to be handled by trigger-driven subscriber flows instead +- Partial updates +- Fields that define `computedFieldTriggerConfig`, because those are expected to be handled by trigger-driven subscriber flows instead @@ -2172,9 +2171,9 @@ Once computed, the field behaves like any other persisted scalar of the authored Typical use cases include: -- filtering or searching by generated transaction ids and external ids -- sorting or reporting on derived numeric or date values -- exposing stable business keys that are derived automatically rather than entered manually +- Filtering or searching by generated transaction ids and external ids +- Sorting or reporting on derived numeric or date values +- Exposing stable business keys that are derived automatically rather than entered manually In practice, `computed` is best understood as a generated persisted field rather than as a transient view-only value. diff --git a/content/docs/developer-docs/metadata_schema/index.mdx b/content/docs/developer-docs/metadata_schema/index.mdx index 8c634b1..e5731a6 100644 --- a/content/docs/developer-docs/metadata_schema/index.mdx +++ b/content/docs/developer-docs/metadata_schema/index.mdx @@ -1,34 +1,34 @@ --- title: Metadata Schema icon: "file-json" -description: Overview of the metadata schema used in SolidX. -summary: This document provides an overview of SolidX's metadata-driven architecture, which enables flexible configuration of both backend and frontend functionality without modifying core code. Metadata can be defined in JSON files or through the admin interface and is synced into the database through seeding. Key components include Module, Model, Field, View, Action, Menu Item, Roles & Permissions, Users, Email/SMS Templates, Media Storage Providers, Scheduled Jobs, Security Rules, List of Values, and Dashboard metadata. The document also explains how to think about seeding as the platform bootstrap step for a working SolidX environment. +description: Reference for the SolidX metadata schema and how it drives runtime behavior. +summary: Covers the major metadata components in SolidX, how metadata is authored and seeded, and how declarative configuration becomes active platform state. sidebar_position: 3.5 solidx_concerns: [add_field_to_existing_layout, add_field_to_a_model, add/update_security_record_rule] --- -import { Box, Database, ToggleLeft, Eye, Zap, Menu, Shield, Users, Mail, Image, Clock, FileWarning, List, LayoutDashboard, CheckCheck } from 'lucide-react'; +import { Box, Database, ToggleLeft, Eye, Zap, Menu, Shield, Users, Mail, Image, Clock, FileWarning, List, LayoutDashboard } from 'lucide-react'; -# Metadata Schema - -## Overview +## Metadata Overview - In SolidX, metadata is not just configuration sitting on the side. It is the **declarative layer that tells the platform what application to become**. - - Models and fields define data structure. - - Views, actions, and menus define application behaviour and navigation. - - Roles, permissions, rules, templates, and settings define platform policy and runtime behaviour. - So the intuition is: when you edit metadata, you are not merely tweaking settings. You are shaping the behaviour of the full stack platform. +In SolidX, metadata is the declarative layer that defines the application the platform will materialize at runtime. + +- Models and fields define data structure. +- Views, actions, and menus define application behavior and navigation. +- Roles, permissions, rules, templates, and settings define platform policy and runtime behavior. + +Editing metadata changes full-stack platform behavior, not only isolated configuration values. -The metadata schema in `SolidX` is designed to provide a flexible and extensible way to define the structure and behavior of various application components. By using a metadata-driven approach, developers can easily customize and extend the functionality of the `SolidX` platform without modifying the core codebase. +The metadata schema in `SolidX` defines the structure and behavior of platform components through declarative configuration rather than direct framework-level rewrites. `SolidX` allows configuring both backend and frontend functionality using metadata configuration. The metadata can either be defined in JSON files or through the admin interface. When any metadata is created or updated through the admin interface, it is stored in the database as well as in the JSON file for the corresponding module. This allows for easy version control and migration of metadata changes across different environments. -Every module needs to have its own metadata file which is then seeded into the database. +Every module needs its own metadata file, which is then seeded into the database. ## Seeding Metadata @@ -36,17 +36,19 @@ Seeding is the process that initializes the database with the metadata and platf -The result of the seeding step is a working SolidX environment, not just a populated database. +The result of the seeding step is a working SolidX environment, not only a populated database. - In SolidX, metadata in JSON is only part of the story. The platform becomes usable when that metadata is seeded into the database so the runtime can discover modules, views, roles, menus, templates, and other platform records. - - A plain database is only persistence. - - A seeded database is a functioning SolidX environment. - - That is why seeding is a bootstrap step, not just sample-data insertion. - So the intuition is: **seeding is how declarative metadata becomes active platform state**. +In SolidX, metadata in JSON is only part of the story. The platform becomes usable when that metadata is seeded into the database so the runtime can discover modules, views, roles, menus, templates, and other platform records. + +- A plain database is only persistence. +- A seeded database is a functioning SolidX environment. +- That is why seeding is a bootstrap step, not only sample-data insertion. + +The key idea is that seeding is how declarative metadata becomes active platform state. ### Why Seeding Matters @@ -121,63 +123,66 @@ Seeding does not only load modules and models. It also initializes several platf Below are the key components of the metadata schema. All the functionality concerning the below components is driven by the metadata schema. - } title="Module Metadata">The root configuration for each module, defining its identity, scope, and lifecycle. - } title="Model Metadata">Defines the data structures (entities) for each module. - } title="Field Metadata">Specifies the individual fields for each model. - } title="View Metadata">Configures how models are displayed (List, Form, Kanban views). - } title="Action Metadata">Defines custom actions tied to models. - } title="Menu Item Metadata">Configures the admin menu structure. - } title="Roles & Permissions">Defines access control rules. - } title="Users">Manages user accounts and profiles. - } title="Email Templates">Configures email notification templates. - } title="SMS Templates">Configures SMS notification templates. - } title="Media Storage Providers">Defines storage backends for media assets. - } title="Scheduled Jobs">Configures recurring background tasks. - } title="Security Rules">Record-level access control rules. - } title="List of Values">Manages reusable dropdown options. - } title="Dashboard Metadata">Configures admin dashboard widgets and analytics. + } title="Module Metadata" href="/docs/developer-docs/metadata_schema/module-metadata">The root configuration for each module, defining its identity, scope, defaults, and lifecycle. + } title="Model Metadata" href="/docs/developer-docs/metadata_schema/model-metadata">Defines the entities for each module, including table mapping, runtime flags, and data-source behavior. + } title="Field Metadata" href="/docs/developer-docs/metadata_schema/field-metadata">Specifies the individual fields for each model, including validation, persistence, relations, and computed behavior. + } title="View Metadata" href="/docs/developer-docs/metadata_schema/view-metadata">Configures how models are rendered through generated list, form, tree, card, and kanban views. + } title="Action Metadata" href="/docs/developer-docs/metadata_schema/action-metadata">Defines built-in and custom actions tied to models, routes, and generated views. + } title="Menu Item Metadata" href="/docs/developer-docs/metadata_schema/menu-item-metadata">Configures the admin navigation structure, menu hierarchy, ordering, and action linkage. + } title="Roles & Permissions" href="/docs/developer-docs/metadata_schema/roles-permissions-metadata">Defines high-level access control through roles and permission assignment. + } title="Users" href="/docs/developer-docs/metadata_schema/users-metadata">Manages seeded user accounts, default identity setup, and role binding. + } title="Email Templates" href="/docs/developer-docs/metadata_schema/email-templates">Configures email notification templates, body references, and activation flags. + } title="SMS Templates" href="/docs/developer-docs/metadata_schema/sms-templates">Configures SMS notification templates, provider template IDs, and text-template behavior. + } title="Media Storage Providers" href="/docs/developer-docs/metadata_schema/media-storage-providers">Defines storage backends for media assets, including filesystem and S3-backed configurations. + } title="Scheduled Jobs" href="/docs/developer-docs/metadata_schema/scheduled-jobs">Configures recurring background tasks, schedules, and execution classes. + } title="Security Rules" href="/docs/developer-docs/metadata_schema/security-rules">Defines record-level access rules, role binding, and filter-based visibility behavior. + } title="List of Values" href="/docs/developer-docs/metadata_schema/list-of-values">Manages reusable enumerations and dropdown options shared across modules and views. + } title="Dashboard Metadata" href="/docs/developer-docs/dashboarding">Covers dashboard configuration, widget composition, and summary-driven admin surfaces. ## Best Practices - - Use kebab-case for internal names (`fees-portal`, `institute-list-view`) - - Use PascalCase for display names (`Fees Portal`, `Institute List View`) - - Use camelCase for field names (`instituteName`, `feeAmount`) + - Use kebab-case for internal names such as `fees-portal` and `institute-list-view`. + - Use PascalCase for display names shown in the UI such as `Fees Portal` and `Institute List View` + - Use camelCase for field names such as `instituteName` and `feeAmount`. - - Always configure roles and security rules - - Use principle of least privilege - - Implement proper data filtering - - Enable audit tracking for sensitive operations + - Configure roles and permission sets early instead of widening access later. + - Add security rules wherever role access alone is not enough to protect records. + - Apply least-privilege access to sensitive models and workflows. - - Use database indexes for frequently queried fields + - Add indexes deliberately for fields that are frequently searched, filtered, joined, or sorted. + - Be deliberate about schema growth as models and generated views expand over time. - - Group related fields logically in forms - - Use appropriate field types for data validation - - Provide helpful field descriptions + - Group related fields logically in generated forms and views. + - Choose field types that match both the data shape and the authoring experience. + - Add descriptions where they improve editor clarity or reduce configuration mistakes. - - Use consistent field configurations - - Version control metadata changes - - Test security rules thoroughly + - Keep field configuration patterns consistent across modules. + - Version metadata changes carefully and review them like application code. + - Test security-sensitive metadata after seeding so runtime behavior matches intent. - - Configure proper field validations - - Use appropriate data types - - Ensure unique constraints where necessary - - Choose appropriate user keys for models. User keys should be unique and stable (i.e should not change over time) for a model - - Use appropriate relation cascading rules + - Configure field validations deliberately rather than relying on UI behavior alone. + - Choose stable and unique user keys that remain meaningful over time. + - Use appropriate data types and relation cascading rules for the lifecycle of the data. -## What's Coming Up +## Worked Tutorials -In the upcoming sections, we'll walk through practical examples that use the metadata schema and explain each attribute in detail. +If you want to see these metadata surfaces applied in a working build flow before reading the individual reference pages, start with one of these tutorials. -These examples are based on the Fees Portal Module (a Fee Collection Module for Educational Institutions). - -If you'd like to learn more about the Fees Portal module itself, you can refer to the detailed guide here: [School Fees Portal Tutorial](../../tutorial/school-fees-portal/index.md) + + + A smaller end-to-end example that shows how module, model, field, view, and action metadata fit together in a simple build flow. + + + A larger multi-module implementation that uses metadata across onboarding, permissions, views, payment workflows, and operational configuration. + + diff --git a/content/docs/developer-docs/metadata_schema/list-of-values.mdx b/content/docs/developer-docs/metadata_schema/list-of-values.mdx index 2f58521..24ebdb3 100644 --- a/content/docs/developer-docs/metadata_schema/list-of-values.mdx +++ b/content/docs/developer-docs/metadata_schema/list-of-values.mdx @@ -1,8 +1,8 @@ --- -title : List of Values +title: List of Values icon: "list" -description : Metadata schema for defining list of values in SolidX applications. -summary: This document describes list of values (LOV) metadata in SolidX, which defines predefined value sets for use in dropdowns and selection fields throughout the application. Each LOV entry includes type (category), value (internal identifier), display text (shown to users), description, default flag, sequence number for ordering, and associated module reference. Examples demonstrate configuring industry types (Healthcare, Information Technology) and regulatory bodies (FCA, SEC, PRA, CBI) with proper sequencing. The metadata ensures data consistency, improves user experience, and provides centralized management of commonly used value lists across the application. +description: Metadata schema for defining list of values in SolidX applications. +summary: Covers the metadata used to define list-of-values entries in SolidX, including type, value, display label, default flag, ordering, and module association. json_pointer: "/listOfValues" jsonpath: "$.listOfValues" parent_component: root @@ -12,9 +12,6 @@ items_attributes_doc: "#list-of-values-metadata-attributes" solidx_concerns: [add_lov_record] --- - - -# List of Values **JSON Pointer:** `/listOfValues` @@ -24,12 +21,13 @@ solidx_concerns: [add_lov_record] ## Overview -List of Values (LOV) are used to define a set of predefined values that can be used in various parts of the SolidX application, such as dropdowns or selection fields. This helps ensure data consistency and improve user experience. +List of Values (LOV) are used to define a set of predefined values that can be used in various parts of the SolidX application, such as dropdowns or selection fields. This helps ensure data consistency and improves user experience. ### Example: List of Values Metadata -Below is an example wherein we define several list of values for different types such as INDUSTRY and REGULATED_BY. +Below is an example where we define several list of values for different types such as `INDUSTRY` and `REGULATED_BY`. - List of Values Schema +
+List of values schema example ``` json { @@ -65,6 +63,7 @@ Below is an example wherein we define several list of values for different types ] } ``` +
### Using the List of Values in Dynamic Selection Fields To use the defined list of values in your application, you need to reference them by creating a dynamic selection field in your model. @@ -107,14 +106,12 @@ To utilize the defined list of values in a dynamic selection field, you can conf } ``` +`ListOfValuesSelectionProvider` is a built-in selection provider that fetches values from the `listOfValues` metadata based on the specified `type`. The `selectionDynamicProviderCtxt` contains a JSON string with the `type` key to filter the LOV entries. +#### Further Reference - ListOfValuesSelectionProvider is a built-in selection provider that fetches values from the `listOfValues` metadata based on the specified `type`. The `selectionDynamicProviderCtxt` contains a JSON string with the `type` key to filter the LOV entries. - - -#### Further Reference - - Understanding Dynamic Selection Fields: See [Dynamic Selection Fields Documentation](../../admin-docs/module-builder/field-management#dynamic-selection) - - Built-in Selection Providers: See [Built-in Selection Providers](../extending/reference/built-in-selection-providers) for full documentation on `ListOfValuesSelectionProvider` and `PseudoForeignKeySelectionProvider` +- Understanding Dynamic Selection Fields: See [Dynamic Selection Fields Documentation](../../admin-docs/module-builder/field-management#dynamic-selection) +- Built-in Selection Providers: See [Built-in Selection Providers](../extending/reference/built-in-selection-providers) for full documentation on `ListOfValuesSelectionProvider` and `PseudoForeignKeySelectionProvider` ### List of Values Metadata Attributes diff --git a/content/docs/developer-docs/metadata_schema/media-storage-providers.mdx b/content/docs/developer-docs/metadata_schema/media-storage-providers.mdx index 56a6d6f..f4623f1 100644 --- a/content/docs/developer-docs/metadata_schema/media-storage-providers.mdx +++ b/content/docs/developer-docs/metadata_schema/media-storage-providers.mdx @@ -2,7 +2,7 @@ title: Storage Providers icon: "hard-drive" description: Metadata schema for defining media storage providers in SolidX applications. -summary: This document explains media storage provider metadata in SolidX, which supports multiple storage options for media files including local filesystem and AWS S3. The metadata includes provider name and type attributes. Default providers (default-filesystem and default-aws-s3) are automatically seeded and don't require explicit JSON configuration. For AWS S3, sensitive credentials (access key, secret key) must be provided via environment variables rather than in JSON for security. The document references the admin documentation for conceptual understanding and provides configuration examples for different storage provider types. +summary: Covers the metadata used to define media storage providers in SolidX, including local filesystem and AWS S3-backed configurations. json_pointer: "/mediaStorageProviders" jsonpath: "$.mediaStorageProviders" parent_component: root @@ -12,10 +12,6 @@ items_attributes_doc: "#media-storage-providers-metadata-attributes" solidx_concerns: [] --- - - - -# Media Storage **JSON Pointer:** `/mediaStorageProviders` @@ -25,11 +21,15 @@ solidx_concerns: [] ## Overview -SOLID supports multiple storage providers for media files, offering flexibility in how and where your media assets are stored. -For a conceptual overview of media storage providers in SolidX, refer to the [Storage Providers](../../admin-docs/media-library/storage-providers.md). +SolidX supports multiple storage providers for media files, giving you flexibility in how and where uploaded assets are stored. + +This section is used to register storage backends such as the local filesystem or AWS S3. For admin-side authoring workflows, refer to the [Storage Providers](../../admin-docs/media-library/storage-providers.md). ## Example: Media Storage Providers Metadata - Media Storage Providers Schema +This example shows two common storage providers: a local filesystem provider and an AWS S3 provider. + +
+Media storage providers schema example ``` json { @@ -47,10 +47,9 @@ For a conceptual overview of media storage providers in SolidX, refer to the [St } ``` +
- -For the media storage provider `default-aws-s3`, you need to provide the following environment variables in your `.env` file or deployment environment: -
+For the `default-aws-s3` provider, supply the following environment variables in `.env` or in the deployment environment: ```bash S3_AWS_ACCESS_KEY= # Only in env, not JSON (for security) @@ -87,4 +86,4 @@ Indicates whether the media files stored in this provider are publicly accessibl ### `signedUrlExpiry` *(number, optional)* Expiry time (in minutes) for signed URLs generated for accessing private media files. -**Applies to** `aws-s3` \ No newline at end of file +**Applies to** `aws-s3` diff --git a/content/docs/developer-docs/metadata_schema/menu-item-metadata.mdx b/content/docs/developer-docs/metadata_schema/menu-item-metadata.mdx index dee7bdb..a4041d1 100644 --- a/content/docs/developer-docs/metadata_schema/menu-item-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/menu-item-metadata.mdx @@ -2,7 +2,7 @@ title: Menu Items icon: "menu" description: Metadata schema for defining menus in SolidX applications. -summary: This document describes menu item metadata in SolidX, which automatically generates and manages the admin panel's navigation structure based on modules and resources. Menu metadata includes display name, unique name, sequence number for ordering, associated action, module reference, parent menu item for hierarchical navigation, role-based access control, and icon names. The system supports nested menu structures through parent-child relationships, enabling complex navigation hierarchies. Examples demonstrate creating multi-level menus for modules like the Fees Portal with home pages, list views, and nested submenus. +summary: Covers the metadata used to define admin navigation in SolidX, including menu hierarchy, ordering, action linkage, module association, and icon selection. json_pointer: "/menus" jsonpath: "$.menus" parent_component: root @@ -11,9 +11,6 @@ items_type: "object" items_attributes_doc: "#menu-item-metadata-attributes" solidx_concerns: [add_custom_menu_action_combo, add_new_role_with_permission, modify_role] --- - - -# Menu Item Metadata **JSON Pointer:** `/menus` @@ -23,13 +20,16 @@ solidx_concerns: [add_custom_menu_action_combo, add_new_role_with_permission, mo ## Overview -SOLID automatically generates and manages the admin panel's menu structure based on your modules and resources. The menu system provides an intuitive way to navigate through your application's features +Menu metadata defines the admin navigation structure generated by SolidX. + +Each menu record binds a user-facing label to an action, assigns ordering, and optionally places the item under a parent menu or behind role-based access rules. -For a conceptual overview of menus in SolidX, refer to the [Menu System Overview](../../admin-docs/modules/menu-structure.md). +For admin-side authoring workflows, refer to the [Menu System Overview](../../admin-docs/modules/menu-structure.md). ### Example: Fee Portal Module Menu Metadata - Menu Schema +
+Menu schema example ``` json { @@ -87,13 +87,10 @@ For a conceptual overview of menus in SolidX, refer to the [Menu System Overview ], } ``` +
-

- - ## Menu Item Metadata Attributes -

@@ -101,7 +98,6 @@ For a conceptual overview of menus in SolidX, refer to the [Menu System Overview Name of the menu item (column/property). **Default:** N/A ---- ### `displayName` *(string, required)* Display name of the menu item (shown in the UI). @@ -150,4 +146,4 @@ Lower numbers appear first. If empty or not provided, menu items are shown in th ### `iconName` *(string, optional)* Name of the icon to display alongside the menu item. Refer to the [Material Icons](https://fonts.google.com/icons?icon.set=Material+Icons) for available icons. -**Default:** N/A \ No newline at end of file +**Default:** N/A diff --git a/content/docs/developer-docs/metadata_schema/model-metadata.mdx b/content/docs/developer-docs/metadata_schema/model-metadata.mdx index 599aed5..aea3720 100644 --- a/content/docs/developer-docs/metadata_schema/model-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/model-metadata.mdx @@ -2,20 +2,16 @@ title: Models icon: "database" description: Overview of the model metadata schema used in SolidX. -summary: This document details the model metadata schema in SolidX, where models represent data structures (entities/tables) within modules. Each model is a semantic, configurable structure that defines specific data types, their attributes, and relationships with other models. Key properties include singular/plural names, display name, data source configuration, table name, soft delete settings, audit logging, internationalization support, exportability, and user key field designation. The metadata also specifies which fields serve as unique identifiers for records and controls various behavioral aspects like draft-publish workflows. +summary: Covers the metadata used to define SolidX models, including naming, table mapping, data-source configuration, lifecycle flags, and runtime behavior. json_pointer: "/moduleMetadata/models" jsonpath: "$.moduleMetadata.models" parent_component: moduleMetadata -type: array, +type: array items_type: "object" items_attributes_doc: "#model-metadata-attributes" solidx_concerns: [create_model_with_fields, add_field_to_a_model, remove_field_from_a_model] --- - - - -# Model Metadata **JSON Pointer:** `/moduleMetadata/models` @@ -26,31 +22,28 @@ solidx_concerns: [create_model_with_fields, add_field_to_a_model, remove_field_f ## Overview -SolidX Models represent the structure of your data within a module. Each model defines a specific type of data, all attributes / fields that a model is made of & its relationships with other models. +Model metadata defines the strcuture of data that exist inside a SolidX module. -Each model is a semantic, configurable data structure that forms the basis of adding custom business logic. +Each model establishes persistence, naming, lifecycle behaviour, and runtime flags for one business entity. Generated APIs, layouts, permissions, relations, and code-generation flows all build on that model definition. - If a module is a business domain, a model is one important noun inside that domain. Models do more than define storage. They become the anchor for generated APIs, permissions, layouts, relations, and backend behavior. - - Think in terms of business records such as venue, institute, fee type, or booking. - - Use model metadata to express identity, persistence, and lifecycle behavior. - - Choose model boundaries carefully because many platform features build on top of them. - So the intuition is: a model is the platform's unit of record and behavior inside a module. + If a module is a business domain, a model is one business record type inside that domain. + + - Think in terms of records such as `venue`, `institute`, `feeType`, or `booking`. + - Use model metadata to express identity, persistence, and lifecycle behaviour. + - Choose model boundaries carefully because many platform features build on top of them. -👉 For a conceptual overview of what a model is, see [Model Management Documentation](/docs/admin-docs/module-builder/model-management). +For admin-side authoring workflows, see [Model Management Documentation](/docs/admin-docs/module-builder/model-management). ### Example: Institute Model
- - - Model Schema - + Model schema example ```json { @@ -94,15 +87,11 @@ Each model is a semantic, configurable data structure that forms the basis of ad }, ... // Other metadata } -``` +```
-

- - -## Model Metadata Attributes -

+## Model Metadata Attributes ### `singularName` *(string, required, unique)* Unique identifier for the model (lowercase, underscores/dashes). @@ -209,13 +198,6 @@ Indicates whether this model maps to a pre-existing legacy table and, if so, how When set to `"existing_id"` or `"generated_id"`, at least one field must be marked as `isPrimaryKey: true`. **Default:** `"none"` -
-
- - -## Related Recipes (TODO) - -
+## Related Recipes 👉 [Model Type Recipes](../../admin-docs/module-builder/model-management#related-recipes) -**Default:** `false` diff --git a/content/docs/developer-docs/metadata_schema/module-metadata.mdx b/content/docs/developer-docs/metadata_schema/module-metadata.mdx index 98e93dd..d65b804 100644 --- a/content/docs/developer-docs/metadata_schema/module-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/module-metadata.mdx @@ -2,7 +2,7 @@ title: Modules icon: "package" description: Overview of the module metadata schema used in SolidX. -summary: This document explains the module metadata schema in SolidX, which represents the top-level building blocks for organizing applications. A module groups related models and functionality under a unified domain (like a Fees Portal module). The metadata includes properties such as module name, display name, description, default data source, menu icon, sequence number, and system flag. Examples demonstrate configuring module metadata for applications, and the document references the admin documentation for conceptual understanding of module management and the hierarchical relationship where modules contain models which contain fields. +summary: Covers the top-level metadata used to define a SolidX module, including identity, data-source defaults, menu behavior, and module-level configuration. json_pointer: "/moduleMetadata" jsonpath: "$.moduleMetadata" parent_component: root @@ -11,10 +11,6 @@ items_attributes_doc: "#module-metadata-attributes" solidx_concerns: [create_module] --- - - -# Module Metadata - **JSON Pointer:** `/moduleMetadata` @@ -23,30 +19,28 @@ solidx_concerns: [create_module] -## Overview +## Overview + +Module metadata defines the top-level boundary of a SolidX business domain. -When creating a new module in SolidX, you're defining a **core building block** of your application. -A module groups together related models and functionality under a **unified domain**. +It identifies the module, establishes its default data-source behaviour, and provides the root container under which related models, views, menus, and other metadata records are organized. - A module is the top-level business boundary in SolidX. It is not just a folder or namespace. It is the container that tells the platform which models, views, menu entries, and behaviors belong to one domain. - - Start by asking: what business capability are we modelling? - - Put closely related models inside the same module. - - Use the module to define the identity of that domain inside the app. - So the intuition is: a module is the platform's unit of business ownership. + A module is the top-level business boundary in SolidX. It is not just a folder or namespace. + + - Start by asking which business capability the module owns. + - Group closely related models, views, actions, and menus inside that boundary. + - Use the module record to establish the identity of that domain across the platform. -👉 For a conceptual overview of what a module is, see [Module Management Documentation](../../admin-docs/module-builder/module-management.md). +For admin-side authoring workflows, see [Module Management Documentation](../../admin-docs/module-builder/module-management.md). -### Example: Fees Portal Module -Below is a module metadata example for a "Fees Portal" module that tracks fee collection requests. +### Example: Fees Portal Module +Below is a representative module record for a `fees-portal` domain.
- - - Module Schema - + Module schema example ```json { @@ -65,17 +59,11 @@ Below is a module metadata example for a "Fees Portal" module that tracks fee co ```
+In this example, `defaultDataSource` is set to `default`, which points to the default TypeORM data source configured in your `app-default-database.module.ts` in your project `solid-api` src folder. - The defaultDataSource is set to "default" here, which refers to the default data source configured in your SolidX instance. This is the TypeORM data source configured in your app-default.database.ts in your project `solid-api` src folder. - - - -

- ## Module Metadata Attributes -

### `name` *(string, required, unique)* diff --git a/content/docs/developer-docs/metadata_schema/predefined-searches.mdx b/content/docs/developer-docs/metadata_schema/predefined-searches.mdx index 24a357a..e338e2b 100644 --- a/content/docs/developer-docs/metadata_schema/predefined-searches.mdx +++ b/content/docs/developer-docs/metadata_schema/predefined-searches.mdx @@ -2,7 +2,7 @@ title: Predefined Searches icon: "search" description: Metadata schema for defining predefined searches in SolidX list views. -summary: This document describes predefined searches metadata in SolidX, which enables configuration of named search presets that appear by default in the search dialog on list views. Each predefined search has a name, an optional description, and a filter expression using query operators. The filters support dynamic placeholders such as {{search}} for user input. Examples demonstrate configuring searches for book titles and availability status. This is useful for surfacing common or business-critical search patterns without requiring users to build filters manually. +summary: Covers named search presets for SolidX list views, including filter expressions, optional descriptions, and dynamic placeholders such as `{{search}}`. json_pointer: "/views/{index}/layout/attrs/predefinedSearches" jsonpath: "$.views[*].layout.attrs.predefinedSearches" parent_component: views @@ -11,7 +11,6 @@ items_type: "object" items_attributes_doc: "#predefined-searches-attributes" --- -# Predefined Searches **JSON Pointer:** `/views/{index}/layout/attrs/predefinedSearches` @@ -28,7 +27,8 @@ Each preset is displayed as a selectable option in the list view's search panel. ## Example: Predefined Searches Metadata - Predefined Searches Schema +
+Predefined searches schema example ``` json { @@ -72,12 +72,9 @@ Each preset is displayed as a selectable option in the list view's search panel. ] } ``` - -

- +

## Predefined Searches Attributes - ### `name` *(string, required, unique within view)* The label displayed for this search preset in the search dialog. Users will see this name when selecting a search option from the list. @@ -117,5 +114,4 @@ The filter expression applied when this search preset is selected. Uses the Soli ``` - The {"{{search}}"} placeholder is replaced at runtime with whatever the user types in the search input. If no placeholder is used, the filter acts as a static preset that does not depend on user input. - +The {"{{search}}"} placeholder is replaced at runtime with the value typed by the user in search input. If no placeholder is used, the filter behaves as a static preset that does not depend on user input. diff --git a/content/docs/developer-docs/metadata_schema/roles-permissions-metadata.mdx b/content/docs/developer-docs/metadata_schema/roles-permissions-metadata.mdx index 38a0130..d38d062 100644 --- a/content/docs/developer-docs/metadata_schema/roles-permissions-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/roles-permissions-metadata.mdx @@ -2,7 +2,7 @@ title: Roles & Permissions icon: "shield" description: Metadata schema for defining roles and permissions in SolidX applications. -summary: This document explains roles and permissions metadata in SolidX, which provides role-based access control at a high level. Roles group permissions and can be assigned to users, while permissions are automatically discovered based on controller actions for fine-grained control. Each role has a name and description, with permissions specified as an array of controller method names (e.g., "InstituteController.create", "InstituteController.findMany"). The system includes a default Admin role with all permissions. Examples demonstrate creating custom roles like Institute Admin with specific permission sets for managing institute-related operations. +summary: Covers the metadata used to define roles, assign permissions, and control high-level access in SolidX. json_pointer: "/roles" jsonpath: "$.roles" parent_component: root @@ -12,8 +12,6 @@ items_attributes_doc: "#roles-permissions-metadata-attributes" solidx_concerns: [add_new_role_with_permission, modify_role] --- - -# Roles & Permissions **JSON Pointer:** `/roles` @@ -24,18 +22,19 @@ solidx_concerns: [add_new_role_with_permission, modify_role] ## Overview -Roles in SolidX provide a way to group permissions and manage access control at a high level. Each role represents a set of permissions that can be assigned to users. -Permissions in SOLID are automatically discovered based on controller actions and provide fine-grained control over what users can do within the system. +Roles and permissions define high-level access control in SolidX. + +Permissions are discovered from backend controller methods and represent individual capabilities such as `InstituteController.findMany` or `InstituteController.update`. Roles package those capabilities into reusable access profiles that can be assigned to users. -By Default `Admin` role is created with all permissions. +By default, the `Admin` role is created with all discovered permissions. - Roles and permissions in SolidX work as a two-layer access model. Permissions represent the fine-grained actions the platform knows about, while roles are the business-facing bundles you assign to users. - - Think of permissions as capabilities discovered from the backend. - - Think of roles as the practical packaging of those capabilities for real users. - - Use roles to express job function, not just technical access flags. - So the intuition is: permissions describe what the system can do, and roles describe who should be allowed to do it. +Roles and permissions work as a two-layer access model. + +- Permissions describe what the system can do. Think of permissions as backend-discovered capabilities. +- Roles describe who should be allowed to do it. Think of roles as the business-facing grouping of those capabilities. +- Use roles to express job function, not only technical access flags. @@ -43,7 +42,8 @@ By Default `Admin` role is created with all permissions. ### Example: Fee Portal Module Roles & Permissions Metadata - Roles & Permissions Schema +
+Roles and permissions schema example ```json { @@ -68,13 +68,10 @@ By Default `Admin` role is created with all permissions. ] } ``` +
-

- - ## Roles & Permissions Metadata Attributes -

### `name` _(string, required, unique)_ @@ -96,6 +93,4 @@ An array of permission strings associated with the role. Each permission corresp -Permissions are automatically discovered based on controller methods in the codebase. So for e.g., if you have a controller for managing institutes with methods like create, the permission `InstituteController.create` will be automatically created. - - +Permissions are discovered from controller methods in the codebase. For example, a controller method such as `InstituteController.create` produces the permission `InstituteController.create`. diff --git a/content/docs/developer-docs/metadata_schema/scheduled-jobs.mdx b/content/docs/developer-docs/metadata_schema/scheduled-jobs.mdx index e4ffbb2..91dc59b 100644 --- a/content/docs/developer-docs/metadata_schema/scheduled-jobs.mdx +++ b/content/docs/developer-docs/metadata_schema/scheduled-jobs.mdx @@ -2,7 +2,7 @@ title: Scheduled Jobs icon: "clock" description: Metadata schema for defining scheduled jobs in SolidX applications. -summary: This document describes scheduled jobs metadata in SolidX, which enables configuration of recurring tasks such as sending notifications, cleaning up records, data synchronization, or regular maintenance. The metadata includes schedule name, active status flag, frequency specification, days of week when the job should run, the job class name to execute, and associated module reference. Examples demonstrate configuring late fee calculation jobs that run at specified intervals. The document links to detailed guides on creating and managing scheduled jobs in the backend customization section. +summary: Covers the metadata used to define recurring jobs in SolidX, including schedule name, frequency, active state, execution class, and module association. json_pointer: "/scheduledJobs" jsonpath: "$.scheduledJobs" parent_component: root @@ -21,13 +21,15 @@ solidx_concerns: [add_scheduled_job]
## Overview -Scheduled jobs in SolidX allow you to run recurring tasks such as sending notifications, cleaning up records, syncing data, or performing regular maintenance. +Scheduled jobs in SolidX let you run recurring background tasks such as sending notifications, cleaning up records, syncing data, or performing regular maintenance. -For a guide on how to create and manage scheduled jobs in SolidX, refer to the [Creating Scheduled Jobs](/docs/developer-docs/extending/backend-customization/scheduled-jobs). +Use this metadata to register the job class, define execution frequency, and control when the job is allowed to run. For a guide on how to create and manage scheduled jobs in SolidX, refer to the [Creating Scheduled Jobs](/docs/developer-docs/extending/backend-customization/scheduled-jobs). ## Example: Scheduled Jobs Metadata +This example configures a scheduled job for late fee calculation. - Scheduled Jobs Schema +
+Scheduled jobs schema example ``` json { @@ -43,6 +45,7 @@ For a guide on how to create and manage scheduled jobs in SolidX, refer to the [ ] } ``` +
## Scheduled Jobs Metadata Attributes @@ -102,12 +105,12 @@ The exact class name of the job implementation to execute (case-sensitive). This **Example:** `"LateFeeCalculatorJob"` -### `dayOfWeek` *(string, mandatory for Weekly frequency)* -Days of the week on which the job should run (applicable for weekly frequency). This should be a JSON array of day names. Please ensure that the value is a valid JSON array string in stringified format. +### `dayOfWeek` *(string, required for `Weekly` frequency)* +Days of the week on which the job should run. This value should be provided as a JSON array of day names in stringified format. **Example:** `["Monday", "Wednesday", "Friday"]` **Applies to:** `Weekly` frequency -Currently the configuration expects json configuration in stringified format. +Currently this configuration expects a stringified JSON array. ### `dayOfMonth` *(number \| null, optional)* Day of the month on which the job should run. Only enforced when `frequency` is `"Monthly"`. diff --git a/content/docs/developer-docs/metadata_schema/security-rules.mdx b/content/docs/developer-docs/metadata_schema/security-rules.mdx index 067f25f..3ca70e4 100644 --- a/content/docs/developer-docs/metadata_schema/security-rules.mdx +++ b/content/docs/developer-docs/metadata_schema/security-rules.mdx @@ -2,7 +2,7 @@ title: Security Rules icon: "lock" description: Metadata schema for defining security rules in SolidX applications. -summary: This document explains security rules metadata in SolidX, which controls data access at the model level to ensure only authorized users can view sensitive information. Each rule includes a name, description, associated role, target model, and security rule configuration with filter conditions. The filter configuration supports complex query structures using operators like $eq with dynamic values such as $activeUserId for user-specific data filtering. Examples demonstrate restricting fee type visibility to institute users through relational filtering across associated models. The document links to detailed guides on creating and managing security rules in the backend customization section. +summary: Covers the metadata used to define model-level access rules, role binding, and filter-based record visibility in SolidX. json_pointer: "/securityRules" jsonpath: "$.securityRules" parent_component: root @@ -12,7 +12,6 @@ items_attributes_doc: "#security-rules-metadata-attributes" solidx_concerns: [add/update_security_record_rule] --- -# Security Rules **JSON Pointer:** `/securityRules` @@ -30,17 +29,20 @@ Security rules are crucial for controlling access to data in SolidX. By defining Roles and permissions decide whether a user can invoke an action at all. Security rules answer a second question: which records should that user actually be able to see or act on? + - Use permissions for action-level access. - - Use security rules for record-level visibility and filtering. - - Treat security rules as business visibility policy encoded in metadata. - So the intuition is: security rules are the row-level guardrails layered on top of role-based access. + - Use security rules for record-level visibility and filtering. + - Treat security rules as business visibility policy encoded in metadata. + +Security rules are the row-level guardrails layered on top of role-based access. For a guide on how to create and manage security rules in SolidX, refer to the [Creating Security Rules](../extending/backend-customization/security-rules). ## Example: Security Rules Metadata - Security Rules Schema +
+Security rules schema example ``` json { @@ -66,12 +68,9 @@ For a guide on how to create and manage security rules in SolidX, refer to the [ ] } ``` - -

- +

## Security Rules Metadata Attributes - @@ -92,8 +91,9 @@ The user key of the model (entity) to which this security rule applies. This hel A JSON object defining the actual security rule configuration. This typically includes filters that determine which records are accessible based on the active user's context. Contains a json object with a `filters` key that defines the filtering logic. The filters object is consistent with the filter structure used in queries, allowing for complex conditions and relationships. -#### Further Reference - - Understanding Filters: See [Filters Documentation](../rest-apis/retrieve) for details on constructing filter objects. +#### Further Reference + +- Understanding Filters: See [Filters Documentation](../rest-apis/retrieve) for details on constructing filter objects. diff --git a/content/docs/developer-docs/metadata_schema/sms-templates.mdx b/content/docs/developer-docs/metadata_schema/sms-templates.mdx index 8736864..8f521f0 100644 --- a/content/docs/developer-docs/metadata_schema/sms-templates.mdx +++ b/content/docs/developer-docs/metadata_schema/sms-templates.mdx @@ -3,19 +3,16 @@ title: SMS icon: "smartphone" description: Metadata schema for populating SMS templates in SolidX applications. -summary: This document describes SMS template metadata in SolidX, which allows creation and management of SMS templates with dynamic content using Handlebars syntax. Templates are stored in separate text files referenced by the metadata and support variables for personalization. Key attributes include template name, display name, body file reference, description, SMS provider template ID, active status, and type (text). The document provides examples of OTP login templates with dynamic variable substitution, file organization guidelines, and links to implementing custom SMS providers for integration with external SMS services like Twilio or AWS SNS. +summary: Covers the metadata used to define SMS templates in SolidX, including body-file references, provider template IDs, activation flags, and text-template behavior. json_pointer: "/smsTemplates" jsonpath: "$.smsTemplates" parent_component: root type: array items_type: "object" -items_attributes_doc: "#email-templates-metadata-attributes" +items_attributes_doc: "#sms-templates-metadata-attributes" solidx_concerns: [create/update_sms_template, new_sms_provider] - - - --- -# SMS Templates + **JSON Pointer:** `/smsTemplates` @@ -24,18 +21,16 @@ solidx_concerns: [create/update_sms_template, new_sms_provider] - - ## Overview -SMS Templates in SOLID allow you to create and manage SMS templates with dynamic content. +SMS templates in SolidX let you define and manage text-message templates with dynamic content. + +The template body is stored in a separate text file referenced by the `body` field. The file contains the actual SMS message and can include Handlebars placeholders for dynamic values. ### Example: SMS Templates Metadata -Below is an example of configuring an SMS template which sends an OTP when a user logs in. +This example defines an OTP template used during login. The `body` field points to a separate text template file. +
- - - SMS Templates Schema - + SMS templates schema example ``` json { @@ -56,26 +51,22 @@ Below is an example of configuring an SMS template which sends an OTP when a use ```
-### Example : SMS Template File -Below is an example of the content of the SMS template file `otp-on-login-custom.handlebars.txt` referenced in the above metadata. This file contains the actual SMS message with dynamic placeholders. +### Example: SMS Template File +Below is an example of the content of the `otp-on-login-custom.handlebars.txt` file referenced by the metadata above. +
- - - SMS Template File - + SMS template file example ```text Hi {{ firstName }}, Login to {{ solidAppName }}, using {{ mobileVerificationTokenOnLogin }} as your verification code. ```
-### Example : Sending SMS Using Template (TODO ticket) -Below is a code snippet demonstrating how to send an SMS using the defined SMS templates via the `SmsServiceFactory`. This example shows how to send an OTP verification SMS to a user. +### Example: Sending SMS Using a Template +This snippet shows how an application service sends an OTP verification message to a user using an authored SMS template via `SmsServiceFactory`. +
- - - SMS Sending Code Snippet - + SMS sending code example ``` ts import { SmsServiceFactory } from 'your-sms-service'; @@ -96,11 +87,7 @@ async sendOtpSms(user: { mobile: string; firstName?: string; username: string, m ```
-

- - ## SMS Templates Metadata Attributes -

### `name` *(string, required, unique)* Unique name for the sms template. It should be in kebab-case format (e.g., `example-template-name`). @@ -111,15 +98,16 @@ Display name for the sms template. ### `body` *(string, required)* - - In the metadata json, the filename of the sms template is specified. The templates are searched for in the `module-metadata//sms-templates/` directory of the module. - - The body is then replaced with the content of the sms template file. This will include plain text content. The body can include dynamic placeholders using Handlebars syntax (e.g., `{{placeholderName}}`), as shown in the [SMS Template file](#example--sms-template-file) above. -#### Further Reference - - **SMS Body Creation:** [SMS Templates Guide](../../admin-docs/notifications/sms-templates.md) +- In metadata JSON, `body` holds the template filename. +- SolidX resolves that file from `module-metadata//sms-templates/`. +- The file content is plain text and can include Handlebars placeholders such as `{{placeholderName}}`. +#### Further Reference +- **SMS Body Creation:** [SMS Templates Guide](../../admin-docs/notifications/sms-templates.md) - Please refer to the [Handlebars Documentation](https://handlebarsjs.com/) for more information on using Handlebars syntax in email templates. +Please refer to the [Handlebars Documentation](https://handlebarsjs.com/) for more information on using Handlebars syntax in SMS templates. ### `smsProviderTemplateId` *(string, optional)* @@ -135,4 +123,4 @@ Indicates whether the SMS template is active. Defaults to `true`. ### `type` *(string, optional)* -Type of the SMS template. Currently supports `text` only. \ No newline at end of file +Type of the SMS template. Currently supports `text` only. diff --git a/content/docs/developer-docs/metadata_schema/users-metadata.mdx b/content/docs/developer-docs/metadata_schema/users-metadata.mdx index f0b432b..3b02be1 100644 --- a/content/docs/developer-docs/metadata_schema/users-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/users-metadata.mdx @@ -2,7 +2,7 @@ title: Users icon: "users" description: Metadata schema for populating users in SolidX applications. -summary: This document describes how to populate initial users in SolidX using metadata configuration. Users can be created with attributes including full name, username, email, mobile number, and optional role assignments. If no password is provided, the system auto-generates secure passwords and emails them to the specified addresses. Users are created with the default role specified in the IAM_DEFAULT_ROLE environment variable, or the Public role if not set. The metadata supports specifying multiple roles per user and includes examples of creating users with different configurations. +summary: Covers the metadata used to create initial users in SolidX, including identity fields, role assignment, and default-password behavior. json_pointer: "/users" jsonpath: "$.users" parent_component: root @@ -21,12 +21,15 @@ solidx_concerns: []
## Overview -We can populate some initial users in the system using the `users` metadata. These users will be created with the default role that is specified in the environment variable `IAM_DEFAULT_ROLE` or `Public` role if the environment variable is not set. +Use the `users` metadata section to populate initial user accounts in the platform. -### Example: Fee Portal Module Users Metadata -Below is an example of how to initialize users using the metadata configuration. The below example creates two users, "John Doe" and "Jane Smith", with their respective details. Since no passwords are provided, the system will auto-generate secure passwords for these users and mail them to the specified email addresses. +Each user record can define identity fields such as full name, username, email, mobile number, and optional role assignments. If no roles are specified for a user, SolidX assigns the role defined by `IAM_DEFAULT_ROLE`. If that environment variable is not set, the `Public` role is used. - Users Schema +### Example: Seeded Users +The example below creates two users with their basic account details. Because no passwords are provided, SolidX generates secure passwords and sends them to the configured email addresses. + +
+Users schema example ``` json { @@ -48,6 +51,7 @@ Below is an example of how to initialize users using the metadata configuration. ] } ``` +
## Users Metadata Attributes @@ -69,4 +73,5 @@ Mobile number of the user. List of roles to be assigned to the user. If not provided, the user will be assigned the default role specified in the environment variable `IAM_DEFAULT_ROLE` or `Public` role if the environment variable is not set. Also note, if roles are provided and the `IAM_DEFAULT_ROLE` is present, it will be added to the list of roles assigned to the user. ## Further Reference + - [Users Management](../../admin-docs/iam/users.md) diff --git a/content/docs/developer-docs/metadata_schema/view-metadata.mdx b/content/docs/developer-docs/metadata_schema/view-metadata.mdx index f1476a6..8790669 100644 --- a/content/docs/developer-docs/metadata_schema/view-metadata.mdx +++ b/content/docs/developer-docs/metadata_schema/view-metadata.mdx @@ -14,7 +14,6 @@ solidx_concerns: [update_layout, add_field_to_existing_layout, remove_field_from import { LayoutGrid, Shield, Gauge } from 'lucide-react'; -# View Metadata **JSON Pointer:** `/views` @@ -27,16 +26,16 @@ import { LayoutGrid, Shield, Gauge } from 'lucide-react'; View metadata defines how SolidX presents models and fields to end users. -If field metadata answers "what does this field mean?", view metadata answers "how should this field appear here?" +If field metadata answers "what does this field mean?", view metadata answers "how should this field appear in this runtime surface?" This page is the primary reference for: -- top-level view records -- layout attrs -- field-node attrs inside layouts -- widget selection through `editWidget` and `viewWidget` -- widget-specific attrs -- real metadata examples for `form`, `list`, and `tree` rendering +- Top-level view records +- Layout attrs +- Field-node attrs inside layouts +- Widget selection through `editWidget` and `viewWidget` +- Widget-specific attrs +- Real metadata examples for `form`, `list`, and `tree` rendering For field semantics, validation intent, persistence behavior, and field-level attrs, see [Field Metadata](./field-metadata). @@ -267,8 +266,8 @@ In list and tree views, `richText` reuses the standard text-column path. It does not currently have dedicated list or tree widgets of its own. In these views, it behaves like a text column and relies on the same shared truncation and search mechanics as other text-style scalar fields. - - + + | Concern | How it works | | --- | --- | @@ -294,13 +293,10 @@ It does not currently have dedicated list or tree widgets of its own. In these v
- - - No additional list or tree widgets are currently registered specifically for `richText`. - - + + ### `json` @@ -308,8 +304,8 @@ Core form rendering is supported for `json`, but list and tree support is curren The core list-column dispatch does not currently include a dedicated `json` renderer, so JSON fields should not be assumed to have the same out-of-the-box list support as scalar text fields. - - + + | Concern | How it works | | --- | --- | @@ -332,13 +328,10 @@ The core list-column dispatch does not currently include a dedicated `json` rend
- - - No dedicated core list or tree widgets are currently registered specifically for `json`. - - + + ### `int` @@ -346,8 +339,8 @@ By default, `int` renders as a numeric column that reuses the shared text-style The core list-column path routes `int` through `SolidIntColumn`, which applies numeric cell styling and then renders values through `DefaultTextListWidget` unless a custom `viewWidget` is provided. - - + + | Concern | How it works | | --- | --- | @@ -371,13 +364,10 @@ The core list-column path routes `int` through `SolidIntColumn`, which applies n
- - - No additional core list or tree widgets are currently registered specifically for `int`. - - + + ### `bigint` @@ -385,8 +375,8 @@ In list and tree views, `bigint` currently reuses the same numeric column path u The core list-column path routes `bigint` through `SolidBigintColumn`, which delegates to `SolidIntColumn`. As a result, `bigint` receives numeric table alignment but still renders through `DefaultTextListWidget` by default. - - + + | Concern | How it works | | --- | --- | @@ -409,13 +399,10 @@ The core list-column path routes `bigint` through `SolidBigintColumn`, which del
- - - No additional core list or tree widgets are currently registered specifically for `bigint`. - - + + ### `decimal` @@ -423,8 +410,8 @@ By default, `decimal` renders as a numeric column that reuses the shared text-st The core list-column path routes `decimal` through `SolidDecimalColumn`, which delegates to the same numeric column implementation used for `int`. This means decimal values inherit the standard text-cell rendering behavior unless a custom `viewWidget` is provided. - - + + | Concern | How it works | | --- | --- | @@ -450,13 +437,10 @@ The core list-column path routes `decimal` through `SolidDecimalColumn`, which d
- - - No additional core list or tree widgets are currently registered specifically for `decimal`. - - + + ### `boolean` @@ -464,8 +448,8 @@ By default, `boolean` renders as a compact true-or-false column. The default list renderer is `DefaultBooleanListWidget`, which turns the stored boolean value into readable output such as `Yes` and `No`. This default path is also where column-level label overrides such as `trueLabel` and `falseLabel` are applied. - - + + | Concern | How it works | | --- | --- | @@ -490,13 +474,10 @@ The default list renderer is `DefaultBooleanListWidget`, which turns the stored
- - - No additional core list or tree widgets are currently registered specifically for `boolean`. - - + + ### `date` @@ -504,8 +485,8 @@ By default, `date` renders as a date-formatted column rather than as plain text. The default list renderer is `DefaultDateListWidget`, which delegates value formatting to the shared date-view component. At the list level, formatting is controlled through the layout `format` attr. - - + + | Concern | How it works | | --- | --- | @@ -529,13 +510,10 @@ The default list renderer is `DefaultDateListWidget`, which delegates value form
- - - No additional core list or tree widgets are currently registered specifically for `date`. - - + + ### `datetime` @@ -543,8 +521,8 @@ By default, `datetime` renders as a formatted date-time column rather than as pl The default list renderer is `DefaultDateTimeListWidget`, which delegates value formatting to the shared date-view component with time display enabled. At the list level, formatting is controlled through the layout `format` attr. - - + + | Concern | How it works | | --- | --- | @@ -568,13 +546,10 @@ The default list renderer is `DefaultDateTimeListWidget`, which delegates value - - - No additional core list or tree widgets are currently registered specifically for `datetime`. - - + + ### `time` @@ -582,8 +557,8 @@ In list and tree views, `time` currently reuses the standard text-column path. The core list-column dispatch sends `time` fields through a dedicated column wrapper, but that wrapper falls back to `DefaultTextListWidget`. As a result, `time` currently behaves more like a text field in list and tree views than like a dedicated time-only renderer. - - + + | Concern | How it works | | --- | --- | @@ -607,13 +582,10 @@ The core list-column dispatch sends `time` fields through a dedicated column wra - - - No additional core list or tree widgets are currently registered specifically for `time`. - - + + ### `email` @@ -621,8 +593,8 @@ In list and tree views, `email` reuses the standard text-column path. The core list-column dispatch sends `email` fields through the same shared renderer used for text-like scalar fields. This means email addresses inherit the standard truncation, search, and text-cell behavior rather than using a dedicated email-specific list widget. - - + + | Concern | How it works | | --- | --- | @@ -646,13 +618,10 @@ The core list-column dispatch sends `email` fields through the same shared rende - - - No additional core list or tree widgets are currently registered specifically for `email`. - - + + ### `password` @@ -660,8 +629,8 @@ Core list and tree rendering should not be assumed for `password`. The core list-column dispatch does not currently include a dedicated password renderer, and password fields are generally not intended for ordinary list presentation. - - + + | Concern | How it works | | --- | --- | @@ -684,13 +653,10 @@ The core list-column dispatch does not currently include a dedicated password re - - - No additional core list or tree widgets are currently registered specifically for `password`. - - + + ### `selectionStatic` @@ -698,8 +664,8 @@ By default, `selectionStatic` renders as a text-style column whose visible value The list path uses `DefaultTextListWidget` through the shared text-column renderer. For single-select values, that shared renderer maps stored values to their human-readable labels using `selectionStaticValues`, so list and tree views show the authored label rather than the raw stored token. - - + + | Concern | How it works | | --- | --- | @@ -723,13 +689,10 @@ The list path uses `DefaultTextListWidget` through the shared text-column render - - - No additional core list or tree widgets are currently registered specifically for `selectionStatic`. - - + + ### `selectionDynamic` @@ -737,8 +700,8 @@ By default, `selectionDynamic` renders as a text-style column whose visible valu Unlike `selectionStatic`, the core list path does not perform provider lookups or label mapping at render time. The shared text widget simply displays the current row value as supplied by the dataset. - - + + | Concern | How it works | | --- | --- | @@ -761,13 +724,10 @@ Unlike `selectionStatic`, the core list path does not perform provider lookups o - - - No additional core list or tree widgets are currently registered specifically for `selectionDynamic`. - - + + ### `many-to-one` @@ -873,9 +833,6 @@ By default, the column uses `DefaultRelationOneToManyListWidget`, which shows th - - - No additional core list or tree widgets are currently registered specifically for `one-to-many`. @@ -983,9 +940,6 @@ By default, the column uses `DefaultMediaSingleListWidget`, which shows an inlin - - - No additional core list or tree widgets are currently registered specifically for `mediaSingle`. @@ -1021,9 +975,6 @@ By default, the column uses `DefaultMediaMultipleListWidget`, which shows the le - - - No additional core list or tree widgets are currently registered specifically for `mediaMultiple`. @@ -1059,9 +1010,6 @@ Instead, SolidX renders the field using the same column style that would normall - - - No additional core list or tree widgets are currently registered specifically for `computed`. @@ -1411,8 +1359,8 @@ By default, `richText` renders as a rich-text editor in edit mode and as formatt The supported `richText` widget surface is intentionally simple at the moment: one default edit widget and one default view widget. - - + + | Concern | How it works | | --- | --- | @@ -1437,13 +1385,10 @@ The supported `richText` widget surface is intentionally simple at the moment: o - - - No additional form widgets are currently registered specifically for `richText`. - - + + ### `json` @@ -1451,8 +1396,8 @@ By default, `json` renders in forms using a JSON-oriented code editor in both ed The supported core `json` widget surface is intentionally simple at the moment: one default edit widget and one default view widget. - - + + | Concern | How it works | | --- | --- | @@ -1476,13 +1421,10 @@ The supported core `json` widget surface is intentionally simple at the moment: - - - No additional core form widgets are currently registered specifically for `json`. - - + + ### `int` @@ -1490,8 +1432,8 @@ By default, `int` renders as a number input in edit mode and as a plain numeric The default edit path uses `DefaultIntegerFormEditWidget`. The default view path uses `DefaultIntegerFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1515,8 +1457,8 @@ The default edit path uses `DefaultIntegerFormEditWidget`. The default view path - - + + | Widget | Use when | Extra attrs | | --- | --- | --- | @@ -1544,13 +1486,10 @@ The default edit path uses `DefaultIntegerFormEditWidget`. The default view path } ``` - - - No additional core form view widgets are currently registered specifically for `int`. - - + + ### `bigint` @@ -1558,8 +1497,8 @@ By default, `bigint` reuses the same whole-number editing experience as `int`. The form field factory currently routes `bigint` through `SolidIntegerField`, so the default edit path uses `DefaultIntegerFormEditWidget` and the default view path uses `DefaultIntegerFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1583,13 +1522,10 @@ The form field factory currently routes `bigint` through `SolidIntegerField`, so - - - No additional core form widgets are currently registered specifically for `bigint`. - - + + ### `decimal` @@ -1597,8 +1533,8 @@ By default, `decimal` renders as a number input in edit mode and as a plain nume The default edit path uses `DefaultDecimalFormEditWidget`. The default view path uses `DefaultDecimalFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1622,13 +1558,10 @@ The default edit path uses `DefaultDecimalFormEditWidget`. The default view path - - - No additional core form widgets are currently registered specifically for `decimal`. - - + + ### `boolean` @@ -1636,8 +1569,8 @@ By default, `boolean` renders as a checkbox-style control in edit mode and as a The default edit path resolves through the `booleanCheckbox` alias to `SolidBooleanCheckboxStyleFormEditWidget`. The default view path uses `DefaultBooleanFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1662,8 +1595,8 @@ The default edit path resolves through the `booleanCheckbox` alias to `SolidBool - - + + | Widget | Use when | Extra attrs | | --- | --- | --- | @@ -1720,13 +1653,10 @@ The default edit path resolves through the `booleanCheckbox` alias to `SolidBool } ``` - - - No additional core form view widgets are currently registered specifically for `boolean`. - - + + ### `date` @@ -1734,8 +1664,8 @@ By default, `date` renders as a date picker in edit mode and as a formatted date The default edit path uses `DefaultDateFormEditWidget`. The default view path uses `DefaultDateFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1762,13 +1692,10 @@ The default edit path uses `DefaultDateFormEditWidget`. The default view path us - - - No additional core form widgets are currently registered specifically for `date`. - - + + ### `datetime` @@ -1776,8 +1703,8 @@ By default, `datetime` renders as a date-time picker in edit mode and as a forma The default edit path uses `DefaultDateTimeFormEditWidget`. The default view path uses `DefaultDateTimeFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1802,13 +1729,10 @@ The default edit path uses `DefaultDateTimeFormEditWidget`. The default view pat - - - No additional core form widgets are currently registered specifically for `datetime`. - - + + ### `time` @@ -1816,8 +1740,8 @@ By default, `time` renders as a time-only picker in edit mode and as a formatted The default edit path uses `DefaultTimeFormEditWidget`. The default view path uses `DefaultTimeFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1841,13 +1765,10 @@ The default edit path uses `DefaultTimeFormEditWidget`. The default view path us - - - No additional core form widgets are currently registered specifically for `time`. - - + + ### `email` @@ -1855,8 +1776,8 @@ By default, `email` renders as an email-oriented input in edit mode and as plain The default edit path uses `DefaultEmailFormEditWidget`. The default read-only display follows the shared plain-text view path used for text-like scalar fields. - - + + | Concern | How it works | | --- | --- | @@ -1880,13 +1801,10 @@ The default edit path uses `DefaultEmailFormEditWidget`. The default read-only d - - - No additional core form widgets are currently registered specifically for `email`. - - + + ### `password` @@ -1894,8 +1812,8 @@ By default, `password` uses two different edit experiences depending on context When a record is being created, the default create path uses `DefaultPasswordFormCreateWidget`, which includes password and confirm-password inputs. When an existing record is being edited, the default edit path uses `DefaultPasswordFormEditWidget`, which opens a controlled change-password dialog. The default view path uses `DefaultPasswordFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1920,13 +1838,10 @@ When a record is being created, the default create path uses `DefaultPasswordFor - - - No additional core form widgets are currently registered specifically for `password`. - - + + ### `selectionStatic` @@ -1934,8 +1849,8 @@ By default, `selectionStatic` renders as an autocomplete-driven picker in edit m The default edit path uses `DefaultSelectionStaticAutocompleteFormEditWidget`. The default view path uses `DefaultSelectionStaticFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -1959,8 +1874,8 @@ The default edit path uses `DefaultSelectionStaticAutocompleteFormEditWidget`. T - - + + | Widget | Use when | Extra attrs | | --- | --- | --- | @@ -2010,13 +1925,10 @@ Important note: this widget supports single-select only. When `multiSelect` or ` } ``` - - - No additional core form view widgets are currently registered specifically for `selectionStatic`. - - + + ### `selectionDynamic` @@ -2024,8 +1936,8 @@ By default, `selectionDynamic` renders as a provider-backed autocomplete in edit The default edit path uses `DefaultSelectionDynamicFormEditWidget`. The default view path uses `DefaultSelectionDynamicFormViewWidget`. - - + + | Concern | How it works | | --- | --- | @@ -2049,13 +1961,10 @@ The default edit path uses `DefaultSelectionDynamicFormEditWidget`. The default - - - No additional core form widgets are currently registered specifically for `selectionDynamic`. - - + + ### `many-to-one` @@ -2374,9 +2283,6 @@ The default edit path uses `DefaultMediaSingleFormEditWidget`. The default view - - - No additional core form widgets are currently registered specifically for `mediaSingle`. @@ -2413,9 +2319,6 @@ The default edit path uses `DefaultMediaMultipleFormEditWidget`. The default vie - - - No additional core form widgets are currently registered specifically for `mediaMultiple`. @@ -2453,9 +2356,6 @@ The default experience uses the built-in computed-field renderer for both edit a - - - No additional core form widgets are currently registered specifically for `computed`. diff --git a/content/docs/developer-docs/prerequisites.mdx b/content/docs/developer-docs/prerequisites.mdx index 685fc0c..6921266 100644 --- a/content/docs/developer-docs/prerequisites.mdx +++ b/content/docs/developer-docs/prerequisites.mdx @@ -1,12 +1,12 @@ --- title: Prerequisites icon: "list-checks" -description: Describes the tools needed before installing SolidX and why they matter. -summary: This document explains the development-machine prerequisites for SolidX, starting with the mental model of what each dependency is for before moving into installation steps. It covers the database, version control, Node.js tooling, and a few development utilities used by the SolidX workflow so developers understand not only what to install, but why those tools are part of the platform setup. +description: Describes the local tools required before installing SolidX and explains why they matter. +summary: Covers the database, version control, Node.js, Python, and supporting CLI dependencies required for SolidX development workflows. --- +## Required Tooling -# Prerequisites @@ -16,17 +16,19 @@ These installation instructions are provided as a **guideline**. Environments di - Think of the SolidX prerequisites as the minimum layers required to make a metadata-driven application development environment work. - - Database: stores both application data and SolidX metadata. - - Git: versions your code and metadata changes safely. - - Node.js + npm: powers solidctl, dependency installation, and local builds. - - Python 3.13+: required for the SolidX MCP server and agent tooling. - - Supporting CLI tools: help with the current development workflow such as code generation and asset copying. - So the intuition is simple: first prepare persistence, then prepare the toolchain, then add the small helper utilities the workflow still depends on. +Think of the SolidX prerequisites as the minimum layers required to make a metadata-driven application development environment work. + +- `Database` stores both application data and SolidX metadata. +- `Git` versions your code and metadata changes safely. +- `Node.js + npm` power `solidctl`, dependency installation, and local builds. +- `Python 3.12+` is required if you plan to use the SolidX MCP server or SolidX agent, because both runtimes are Python-based. +- `Supporting CLI tools` help with workflow steps such as code generation and asset handling. + +The setup order is straightforward: prepare persistence first, then the core toolchain, then the smaller helper utilities the workflow depends on. -## 1. Database Setup +## 1. Database Setup ### Why this matters @@ -34,9 +36,9 @@ SolidX is a metadata-driven platform. That means the database is not just storin So when we say “set up the database,” what we really mean is: -- prepare the persistence layer for your application data, -- prepare the persistence layer for SolidX metadata, -- and make sure your local project has somewhere to seed and run against. +- Prepare the persistence layer for your application data. +- Prepare the persistence layer for SolidX metadata. +- Ensure the local project has somewhere to seed and run against. This guide assumes you're using **PostgreSQL** as your database. @@ -44,9 +46,9 @@ This guide assumes you're using **PostgreSQL** as your database. If you're using a different database, please refer to its official documentation. -### Installing PostgreSQL +### Installing PostgreSQL -#### On Ubuntu / macOS +#### On Ubuntu / macOS Follow [DigitalOcean's guide](https://www.digitalocean.com/community/tutorials/how-to-install-postgresql-on-ubuntu-22-04-quickstart) for detailed installation instructions. @@ -65,12 +67,7 @@ psql --version systemctl status postgresql --no-pager ``` -#### Create a PostgreSQL User and Database - -

- - Create a PostgreSQL User and Database -

+#### Create a PostgreSQL User and Database 1. Create a user: @@ -112,15 +109,12 @@ SolidX projects are normal application codebases. Your metadata, backend code, f That means Git is not optional in practice if you want to: -- collaborate with other developers, -- version metadata changes safely, -- review changes, -- and move work across environments cleanly. +- Collaborate with other developers. +- Version metadata changes safely. +- Review changes. +- Move work across environments cleanly. -

- - On Ubuntu / macOS -

+#### On Ubuntu / macOS @@ -152,15 +146,12 @@ Node.js is the runtime behind the project tooling for SolidX development. You need it because: - `solidctl` runs through the Node.js toolchain, -- project dependencies for `solid-api` and `solid-ui` are installed through npm, -- and local build/dev workflows depend on a working Node environment. +- Project dependencies for `solid-api` and `solid-ui` are installed through npm. +- Local build/dev workflows depend on a working Node environment. We recommend `nvm` because different projects may move across Node versions over time, and version management tends to keep development machines healthier. -

- - On Ubuntu / macOS -

+#### On Ubuntu / macOS @@ -186,19 +177,15 @@ npm -v --- -## 4. Python 3.13+ +## 4. Python 3.12+ ### Why this matters -Python is required if you plan to install or run the **SolidX MCP server** or use the **SolidX agent**. These components are Python-based and depend on features available only in Python 3.13 and above. +Python is required if you plan to install or run the **SolidX MCP server** or use the **SolidX agent**, because both runtimes are Python-based. If you are only working with the core SolidX application (API + UI), Python is not needed. It becomes a requirement the moment you bring in the MCP server or agent tooling. -

- - On Ubuntu / macOS - -

+#### On Ubuntu / macOS @@ -210,36 +197,30 @@ We recommend using [pyenv](https://github.com/pyenv/pyenv) to manage Python vers # Install pyenv (Ubuntu / macOS) curl https://pyenv.run | bash -# Reload shell, then install Python 3.13 -pyenv install 3.13 -pyenv global 3.13 +# Reload shell, then install Python 3.12 +pyenv install 3.12 +pyenv global 3.12 # Validate installation: -python --version # should show Python 3.13.x +python --version # should show Python 3.12.x pip --version ``` -On macOS you can also use Homebrew: `brew install python@3.13`. On Ubuntu, use the [deadsnakes PPA](https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa) if 3.13 is not available in the default apt repos. +On macOS you can also use Homebrew: `brew install python@3.12`. On Ubuntu, use the [deadsnakes PPA](https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa) if 3.12 is not available in the default apt repos. --- -## 5. Install schematics-cli +## 5. Install `schematics-cli` ### Why this matters -This tool exists because parts of the SolidX development workflow still use schematics-based generation. +SolidX uses Angular schematics to generate parts of the backend codebase, including controllers and services. -Conceptually, this belongs to the **code-generation support layer**, not the core runtime of your app. That is why it is only needed on development machines. - - -This is only required on development machines, not on production servers. SolidX uses Angular schematics for generating backend controllers and services. - - -
+Because this is part of the code-generation workflow rather than the application runtime, `schematics-cli` is only needed on development machines and not on production servers. @@ -247,8 +228,6 @@ Alternatively, you can install it locally in your project and run via `npx`. Che - - ```bash npm install -g @angular-devkit/schematics-cli @@ -258,19 +237,13 @@ schematics --version --- -## 6. Install copyfiles +## 6. Install `copyfiles` ### Why this matters -This utility supports parts of the asset-copying workflow used during development and build setup. - -Like `schematics-cli`, this is not part of the core business runtime of your application. It is a developer convenience and workflow dependency. - - -This is only required on development machines, not on production servers. SolidX uses copyfiles to copy static files. - +SolidX uses `copyfiles` during parts of the development and build setup workflow to move static assets into the expected project locations. -
+Like `schematics-cli`, this belongs to the development toolchain rather than the application runtime, so it is only needed on development machines and not on production servers. @@ -278,13 +251,9 @@ If you prefer, you can add copyfiles as a project dependency and use it via `npx - - ```bash npm install -g copyfiles # Validate installation: copyfiles --help | head -n 5 ``` - - diff --git a/content/docs/developer-docs/project-structure.mdx b/content/docs/developer-docs/project-structure.mdx index bfd8f50..c1a471b 100644 --- a/content/docs/developer-docs/project-structure.mdx +++ b/content/docs/developer-docs/project-structure.mdx @@ -1,202 +1,192 @@ --- title: Project Structure icon: "folder-tree" -description: Overview of the folder structure for a SolidX fullstack application. -summary: This document provides a practical overview of the SolidX project structure, organized into backend (`solid-api`) and frontend (`solid-ui`) applications. The backend is a NestJS application that contains source code, module metadata, logs, uploaded media, and rebuild scripts. The frontend is a Vite + React application that boots the SolidX UI shell from `src/`, registers project-specific UI modules, and composes routes, reducers, middleware, and assets on top of `@solidxai/core-ui`. The document also highlights key SolidX dependencies, debugging configuration, and upgrade scripts. +description: Describes the standard SolidX workspace layout across `solid-api`, `solid-ui`, and shared project files. +summary: Explains how a SolidX workspace is organized across the NestJS backend, the React frontend, generated metadata, module-owned extensions, and supporting scripts. solidx_concerns: [] --- +import { File, Files, Folder } from 'fumadocs-ui/components/files'; +## Workspace Layout -# Project Structure - -This project is organized into a backend API (`solid-api`) and a frontend UI (`solid-ui`) along with supporting scripts and configurations. +This workspace is organized into a backend application (`solid-api`), a frontend application (`solid-ui`), and supporting scripts and configuration. - SolidX is designed to help you build full-stack applications, not just isolated backend services or isolated frontend sites. - - solid-api: owns metadata, persistence, APIs, business logic, and backend execution. - - solid-ui: owns the browser application, project-specific UI modules, routes, and user-facing workflows. - - Shared SolidX packages: connect those two layers through metadata, generated structure, shared UI building blocks, and common conventions. - So the intuition is: a SolidX project is a coordinated full-stack workspace where backend and frontend evolve together, rather than two unrelated folders living side by side. +SolidX is designed as a coordinated full-stack application workspace rather than a loose pairing of an API repository and a frontend repository. - +- `solid-api` owns metadata, persistence, APIs, domain logic, and backend execution. +- `solid-ui` owns the browser application, project-specific UI modules, routes, and user-facing workflows. +- Shared SolidX packages connect both layers through metadata, generated structure, shared runtime primitives, and framework conventions. -```bash -. -├── .vscode/ # VS Code settings -├── solid-api/ # Backend API (NestJS) -├── solid-ui/ # Frontend UI (Vite + React) -└── upgrade.sh # SolidX upgrade script -``` +The project structure reflects a coordinated workspace in which backend and frontend evolve against the same metadata-defined application model. -## solid-api/ - Backend (NestJS & TypeORM) +
-This folder contains all backend services, business logic, and configurations. +## Top-Level View - + + + + + + + + + + + + + + -

- API Mental Model -

- Think of solid-api as the system-of-record side of a SolidX application. - - It owns your domain models and metadata. - - It exposes the generated and custom API surface. - - It contains the backend extension points for business logic, security, workflows, and integrations. - So when you look at the backend folder structure, you should read it as: metadata + generated structure + custom backend logic. +## Runtime Areas -
+Use the tabs below to inspect the two main application runtimes in a standard SolidX workspace. -```bash -solid-api/ -├── .env, .gitignore, etc. # Config and ignore files -├── logs/ # Application / Error logs -├── media-files-storage/ # Uploaded or generated files -├── media-uploads/ # Temporary upload folder -├── module-metadata/ # Module metadata (JSON) -├── src/ # Source code for the backend -├── test/ # E2E tests -├── rebuild*.sh / refresh.bat # Rebuild and refresh scripts -``` + + + ### Backend (NestJS & TypeORM) -

- + This folder contains backend services, business logic, metadata, persistence wiring, and the generated or custom API surface. - ### Notable Subfolders -

+ + `solid-api` is the system-of-record side of a SolidX application. - - `src/` - - Contains `main.ts` (entry point for the SolidX backend) and all SolidX modules like: - - `fees-portal/` - - `main-cli.ts` -> entry point for the SolidX cli commands. - - `app.module.ts` -> Contains the application module configuration. - - `app-default-database.module.ts` -> Contains all the database configuration. + - It owns your domain models and metadata. + - It exposes both the generated and custom API surface. + - It contains the backend extension points for business logic, security, workflows, and integrations. -

- + The backend folder structure is the composition of metadata, generated runtime structure, and custom backend code. - ### SolidX dependencies -

- - `@solidxai/core` - - Contains the core SolidX module which provides the core backend services for SolidX. - - `@solidxai/code-builder` - - Contains the functionality for generating the code in the SolidX backend. +
+ ```bash + solid-api/ + ├── .env, .gitignore, etc. # Config and ignore files + ├── logs/ # Application / Error logs + ├── media-files-storage/ # Uploaded or generated files + ├── media-uploads/ # Temporary upload folder + ├── module-metadata/ # Module metadata (JSON) + ├── src/ # Source code for the backend + ├── test/ # E2E tests + ├── rebuild*.sh / refresh.bat # Rebuild and refresh scripts + ``` -

- + #### Key Files and Folders - ### SolidX modules -

+ - `src/` + - Contains `main.ts` as the backend entry point and all SolidX modules, such as `fees-portal/`. + - `main-cli.ts` is the entry point for SolidX CLI-driven backend commands. + - `app.module.ts` contains the application module configuration. + - `app-default-database.module.ts` contains the default database configuration. - - - A SolidX module is a logical container that groups together related models and functionality under a unified domain or feature area e.g `fees-portal`. - - You can find the structure for a SolidX module here [Generated Code](../developer-docs/extending/code-generation/index.md). - --- + #### SolidX Backend Packages -## solid-ui/ - Frontend (Vite & React) + - `@solidxai/core` provides the core SolidX backend runtime and shared services. + - `@solidxai/code-builder` provides the backend code-generation functionality used by SolidX. -The frontend is built as a Vite + React application. The generated app is intentionally thin: it bootstraps routing, theming, and Redux wiring, then layers project-specific UI modules on top of the shared `@solidxai/core-ui` package. + #### Module Layout - + - A SolidX module is a logical container that groups related models and functionality under a unified domain or feature area, such as `fees-portal`. + - For the generated structure of a SolidX module, see [Generated Code](/docs/developer-docs/extending/code-generation). -

- UI Mental Model -

- Think of solid-ui as the application shell and user-experience layer of your SolidX project. - - The shared SolidX UI package provides the common runtime, layouts, and extension points. - - Your project adds module-specific routes, dashboards, widgets, Redux integrations, and custom pages on top of that shell. - - The frontend is convention-driven: it is intentionally lightweight at the root, and most project-specific behaviour is added through module folders and *.ui-module.ts registration. - So when you read the frontend structure, the key idea is: small app shell, project-specific modules layered on top. +
+ -
+ ### Frontend (Vite & React) -```bash -solid-ui/ -├── .env, .gitignore # Environment config and ignore files -├── dist/ # Production build output -├── index.html # Vite HTML entry -├── public/ # Static assets copied as-is -├── src/ # Application bootstrap and project-specific UI modules -├── local_packages/ # Optional locally linked SolidX packages -├── package.json # Scripts and dependencies -├── tsconfig*.json # TypeScript configuration -├── vite.config.ts # Vite configuration -├── eslint.config.js # Lint configuration -├── deploy.sh # Project deployment helper (if present) -``` + The generated frontend is intentionally thin: it bootstraps routing, theming, and Redux wiring, then layers project-specific UI modules on top of the shared `@solidxai/core-ui` package. + -

- + `solid-ui` is the application shell and user-experience layer of the project. - ### Notable Subfolders -

+ - The shared SolidX UI package provides the common runtime, layouts, and extension points. + - The consuming project contributes module-specific routes, dashboards, widgets, Redux integrations, and custom pages on top of that shell. + - The frontend is convention-driven: most project-specific behavior is registered through module folders and `*.ui-module.ts` manifests. + + The frontend structure is a thin runtime shell with project-specific modules layered on top. + +
+ + ```bash + solid-ui/ + ├── .env, .gitignore # Environment config and ignore files + ├── dist/ # Production build output + ├── index.html # Vite HTML entry + ├── public/ # Static assets copied as-is + ├── src/ # Application bootstrap and project-specific UI modules + ├── local_packages/ # Optional locally linked SolidX packages + ├── package.json # Scripts and dependencies + ├── tsconfig*.json # TypeScript configuration + ├── vite.config.ts # Vite configuration + ├── eslint.config.js # Lint configuration + ├── deploy.sh # Project deployment helper (if present) + ``` + + #### Key Files and Folders - `src/` - Contains the application bootstrap and all project-specific SolidX UI extensions. - Common entry files include: - - `main.tsx` -> mounts the React app. - - `App.tsx` -> wraps the app with the application router, store, layout, theme, and event-listener providers required by SolidX. - - `AppRoutes.tsx` -> creates the route tree by calling `getSolidRoutes(...)` from `@solidxai/core-ui`. - - `solid-ui-modules.ts` -> auto-discovers `*.ui-module.ts` files, registers their extensions, and builds the combined runtime for routes, reducers, and middleware. + - `main.tsx`, which mounts the React app. + - `App.tsx`, which wraps the app with the router, store, layout, theme, and other required SolidX providers. + - `AppRoutes.tsx`, which creates the route tree by calling `getSolidRoutes(...)` from `@solidxai/core-ui`. + - `solid-ui-modules.ts`, which auto-discovers `*.ui-module.ts` files, registers their extensions, and builds the combined runtime for routes, reducers, and middleware. - App-specific features usually live under a module folder such as `src/venue/` or `src/fees-portal/`. - A typical module folder contains: - - `*.ui-module.ts` -> the module registration file that contributes custom routes, extension components, extension functions, reducers, and middleware. - - `admin-layout/` -> overrides or extends generated admin layouts with custom widgets, actions, and form/list behavior. - - `custom-layout/` -> fully custom pages such as dashboards, login pages, and home screens. - - `redux/` -> RTK Query APIs or other Redux slices owned by the module. - - `utils/` -> module-specific helpers such as export utilities or formatting logic. + - `*.ui-module.ts`, the module registration file that contributes custom routes, extension components, extension functions, reducers, and middleware. + - `admin-layout/`, which overrides or extends generated admin layouts with custom widgets, actions, and form/list behavior. + - `custom-layout/`, which contains fully custom pages such as dashboards, login pages, and home screens. + - `redux/`, which holds RTK Query APIs or other Redux slices owned by the module. + - `utils/`, which contains module-specific helpers such as export utilities or formatting logic. - `public/` - Contains static files such as logos, icons, uploaded brand assets, and theme resources. - Theme files from `@solidxai/core-ui` are often copied here during `postinstall`. - `local_packages/` - Used when developing against local builds of shared SolidX packages instead of published npm versions. + #### SolidX Frontend Package + + - `@solidxai/core-ui` + - Contains the shared SolidX UI framework used by project apps. + - Provides: + - Route generation via `getSolidRoutes(...)` + - Application providers such as `StoreProvider`, `LayoutProvider`, and `SolidThemeProvider` + - Reusable admin pages, auth flows, layouts, widgets, and extension points + - Shared Redux helpers, hooks, adapters, resources, and themes + + #### Key `@solidxai/core-ui` Folders + + ```bash + solid-core-ui/src/ + ├── adapters/ # Auth and integration adapters + ├── components/ # Shared UI components + ├── hooks/ # Reusable React hooks + ├── layouts/ # Layout primitives and admin layout building blocks + ├── modules/ # Shared module-level UI behavior + ├── redux/ # Store helpers, APIs, hooks, and features + ├── resources/ # Themes, fonts, images, and stylesheets + ├── routes/ # Shared route definitions and guards + ├── types/ # Shared TypeScript types + └── ui/ # Higher-level UI exports and composition helpers + ``` + + + + +## Debugging - VS Code - - - -

- - - ### SolidX dependencies -

- -- `@solidxai/core-ui` - - Contains the shared SolidX UI framework used by project apps. - - Provides: - - Route generation via `getSolidRoutes(...)` - - Application providers such as `StoreProvider`, `LayoutProvider`, and `SolidThemeProvider` - - Reusable admin pages, auth flows, layouts, widgets, and extension points - - Shared Redux helpers, hooks, adapters, resources, and themes - -### Key `@solidxai/core-ui` folders - -```bash -solid-core-ui/src/ -├── adapters/ # Auth and integration adapters -├── components/ # Shared UI components -├── hooks/ # Reusable React hooks -├── layouts/ # Layout primitives and admin layout building blocks -├── modules/ # Shared module-level UI behavior -├── redux/ # Store helpers, APIs, hooks, and features -├── resources/ # Themes, fonts, images, and stylesheets -├── routes/ # Shared route definitions and guards -├── types/ # Shared TypeScript types -└── ui/ # Higher-level UI exports and composition helpers -``` - -## Debugging - VS Code Contains editor-specific configurations like `launch.json` for debugging and IDE behavior. -## Upgrade Scripts +## Upgrade Scripts + `upgrade.sh`: Used for upgrading the core SolidX backend/frontend dependencies. -
    -
  • All environment variables are stored in .env files within each app folder.
  • -
+All environment variables are stored in `.env` files within each app folder.
diff --git a/content/docs/developer-docs/rest-apis/authentication/index.mdx b/content/docs/developer-docs/rest-apis/authentication/index.mdx index 0f0a619..1d1c3dc 100644 --- a/content/docs/developer-docs/rest-apis/authentication/index.mdx +++ b/content/docs/developer-docs/rest-apis/authentication/index.mdx @@ -2,21 +2,25 @@ description: This section elaborates on the authentication APIs provided for the different authentication providers. title: Authentication icon: "lock" -summary: This document provides an overview of the authentication mechanisms supported by SolidX. The platform offers three authentication providers - Password-based authentication (the default method using username and password), OTP authentication (using One-Time Passwords for secure login), and OAuth authentication (currently supporting Google as an OAuth provider for social login integration). +summary: Covers password, OTP, and OAuth-based authentication flows and the API surfaces associated with each provider. --- - Authentication providers in SolidX are different entry paths into the same platform session model. The provider changes how identity is verified, but the goal stays the same: establish a trusted user session that the rest of the platform can authorize. + Authentication providers in SolidX are different entry paths into the same platform session model. The provider changes how identity is verified, but the goal stays the same to establish a trusted user session that the rest of the platform can authorize. + - Password is the standard username-and-password flow. - - OTP is useful when short-lived verification is preferred. - - OAuth is useful when identity should be delegated to an external provider. - So the intuition is: these are alternative authentication strategies for the same secured application surface. + - OTP is useful when short-lived verification is preferred. + - OAuth is useful when identity should be delegated to an external provider. + + These are alternative authentication strategies for the same secured application surface. +## Authentication Providers + SolidX supports the below authentication providers: -- **Password**: This is the default authentication provider that uses username and password for authentication. -- **OTP**: This provider uses One-Time Passwords for authentication. -- **OAuth**: This provider uses OAuth for authentication. - - Currently, SolidX supports Google as an OAuth provider. + +- **Password**: The default provider for username-and-password login flows. +- **OTP**: Useful when authentication should rely on short-lived verification codes. +- **OAuth**: Delegate identity to an external provider. The current platform documentation covers the supported OAuth provider flows. diff --git a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.md b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.mdx similarity index 82% rename from content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.md rename to content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.mdx index da50718..3a67448 100644 --- a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.md +++ b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/facebook.mdx @@ -5,9 +5,6 @@ description: Guide to configuring Facebook (Meta) OAuth authentication summary: This guide covers the end-to-end process of setting up Facebook OAuth for your SolidX application, including Meta for Developers app configuration, and environment variable setup. --- - -# Facebook OAuth Authentication - ## Overview This document provides a guide on how to configure and use Facebook OAuth authentication. The implementation allows users to sign in using their Facebook (Meta) accounts. @@ -58,9 +55,23 @@ IAM_FACEBOOK_OAUTH_REDIRECT_URL=https://localhost:3000/auth/facebook/callback ## Authentication Flow -1. **User clicks the Facebook sign-in button** in your app. -2. **Your app redirects to Facebook's login page** for authentication. -3. **User logs in with their Facebook account** and grants your app permission to access their email and profile. -4. **Facebook sends back a confirmation** that the user is authenticated. -5. **Your app receives the confirmation** and creates an internal session for that user. -6. **Your app logs the user in** and they can now access your app. + + + **User clicks the Facebook sign-in button** in your app. + + + **Your app redirects to Facebook's login page** for authentication. + + + **User logs in with their Facebook account** and grants your app permission to access their email and profile. + + + **Facebook sends back a confirmation** that the user is authenticated. + + + **Your app receives the confirmation** and creates an internal session for that user. + + + **Your app logs the user in** and they can now access your app. + + diff --git a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.md b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.mdx similarity index 82% rename from content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.md rename to content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.mdx index 948ab8c..dfcde5a 100644 --- a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.md +++ b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/google.mdx @@ -5,9 +5,6 @@ description: Guide to configuring Google OAuth authentication summary: This guide covers the end-to-end process of setting up Google OAuth for your SolidX application, including Google Cloud Console configuration, environment variable setup, and understanding the authentication flow. --- - -# Google OAuth Authentication - ## Overview This document provides a guide on how to configure and use Google OAuth authentication. The implementation allows users to sign in using their Google accounts. @@ -60,9 +57,23 @@ IAM_GOOGLE_OAUTH_REDIRECT_URL=https://localhost:4200/auth/google/callback ## Authentication Flow -1. **User clicks the Google sign-in button** in your app. -2. **Your app redirects to Google's login page** for authentication. -3. **User logs in with their Google account** and grants your app permission to access their email and profile. -4. **Google sends back a confirmation** that the user is authenticated. -5. **Your app receives the confirmation** and creates an internal session for that user. -6. **Your app logs the user in** and they can now access your app. + + + **User clicks the Google sign-in button** in your app. + + + **Your app redirects to Google's login page** for authentication. + + + **User logs in with their Google account** and grants your app permission to access their email and profile. + + + **Google sends back a confirmation** that the user is authenticated. + + + **Your app receives the confirmation** and creates an internal session for that user. + + + **Your app logs the user in** and they can now access your app. + + diff --git a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/index.mdx b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/index.mdx index 419fac4..e801748 100644 --- a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/index.mdx +++ b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/index.mdx @@ -2,12 +2,12 @@ title: OAuth icon: "key-round" description: Information about OAuth-based authentication methods -summary: Simple overview of OAuth authentication in SolidX, including Google, Facebook, Microsoft, LinkedIn, Twitter/X, and custom OAuth providers. +summary: Covers the OAuth authentication model in SolidX and the supported external identity-provider integrations. --- import { Globe } from 'lucide-react'; -# OAuth methods +## OAuth Providers SolidX supports several OAuth sign-in methods. You can use built-in providers or connect with other OAuth services. diff --git a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.md b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.mdx similarity index 83% rename from content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.md rename to content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.mdx index f51d382..d4c966a 100644 --- a/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.md +++ b/content/docs/developer-docs/rest-apis/authentication/oauth-authentication/microsoft.mdx @@ -5,9 +5,6 @@ description: Guide to configuring Microsoft OAuth authentication summary: This guide covers the end-to-end process of setting up Microsoft OAuth (Entra ID) for your SolidX application, including Azure Portal configuration and environment variable setup. --- - -# Microsoft OAuth Authentication - ## Overview This document provides a guide on how to configure and use Microsoft OAuth authentication. The implementation uses Microsoft Entra ID (formerly Azure Active Directory) to allow users to sign in with their Microsoft accounts. @@ -59,9 +56,23 @@ IAM_MICROSOFT_OAUTH_REDIRECT_URL=http://localhost:4200/auth/microsoft/callback ## Authentication Flow -1. **User clicks the Microsoft sign-in button** in your app. -2. **Your app redirects to Microsoft's login page** for authentication. -3. **User logs in with their Microsoft account** and grants your app permission to access their email and profile. -4. **Microsoft sends back a confirmation** that the user is authenticated. -5. **Your app receives the confirmation** and creates an internal session for that user. -6. **Your app logs the user in** and they can now access your app. + + + **User clicks the Microsoft sign-in button** in your app. + + + **Your app redirects to Microsoft's login page** for authentication. + + + **User logs in with their Microsoft account** and grants your app permission to access their email and profile. + + + **Microsoft sends back a confirmation** that the user is authenticated. + + + **Your app receives the confirmation** and creates an internal session for that user. + + + **Your app logs the user in** and they can now access your app. + + diff --git a/content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.md b/content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.mdx similarity index 75% rename from content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.md rename to content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.mdx index e292efc..c7558fa 100644 --- a/content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.md +++ b/content/docs/developer-docs/rest-apis/authentication/otp-authentication/index.mdx @@ -8,13 +8,11 @@ summary: Details SolidX OTP-based authentication mechanism with comprehensive AP -# OTP Authentication +## OTP Authentication Flow This section covers the OTP-based authentication APIs available in SolidX. - - -## Implementation Overview +## Implementation Overview SolidX provides a comprehensive OTP-based authentication mechanism with the following endpoints: @@ -23,9 +21,9 @@ SolidX provides a comprehensive OTP-based authentication mechanism with the foll -## 1. Register +## 1. Register -### 1.1 Initiate Registration +### 1.1 Initiate Registration Allows users to register using their username, email, or mobile number through OTP verification. @@ -37,43 +35,27 @@ The registration process is divided into two steps: The `validationSources` field in the request body specifies which sources (`email`, `mobile`) should be validated. This can be customized via environment variables or overridden via the `transactional` flag in the request. -

- - -### Endpoint -

+### Endpoint ``` POST /api/iam/otp/register/initiate ``` -

- - -### Environment Variables -

+### Environment Variables - `IAM_PASSWORD_LESS_REGISTRATION`: Enables/disables OTP registration. - `IAM_OTP_EXPIRY`: OTP expiry time (default: 5 mins). - `IAM_PASSWORD_LESS_REGISTRATION_VALIDATE_WHAT`: Values can be `email`, `mobile`, or both. -

- - -### Headers -

+### Headers ```http Content-Type: application/json ``` -

- - -### Request Body -

+### Request Body ```json { @@ -85,11 +67,7 @@ Content-Type: application/json } ``` -

- - -### Response Body -

+### Response Body ```json { @@ -99,27 +77,19 @@ Content-Type: application/json -### 1.2 Confirm Registration +### 1.2 Confirm Registration ``` POST /api/iam/otp/register/confirm ``` -

- - -### Headers -

+### Headers ```http Content-Type: application/json ``` -

- - -### Request Body -

+### Request Body ```json { @@ -129,11 +99,7 @@ Content-Type: application/json } ``` -

- - -### Response Body -

+### Response Body ```json { @@ -144,48 +110,34 @@ Content-Type: application/json -## 2. Login +## 2. Login -### 2.1 Initiate Login +### 2.1 Initiate Login Allows users to log in using username, email, or mobile through OTP. Similar to registration, the `validationSources` and environment variables control OTP delivery. -

- - -### Endpoint -

+### Endpoint ``` POST /api/iam/otp/login/initiate ``` -### Environment Variables +### Environment Variables - `IAM_PASSWORD_LESS_REGISTRATION`: Enables/disables OTP login. - `IAM_OTP_EXPIRY`: OTP expiry time (default: 5 mins). - `IAM_PASSWORD_LESS_LOGIN_VALIDATE_WHAT`: What to validate during login. -

- - -### Headers -

+### Headers ```http Content-Type: application/json ``` -

- - -### Request Body -

- - +### Request Body ```json { @@ -194,11 +146,7 @@ Content-Type: application/json } ``` -

- - -### Response Body -

+### Response Body ```json { @@ -208,30 +156,20 @@ Content-Type: application/json -### 2.2 Confirm Login +### 2.2 Confirm Login ``` POST /api/iam/otp/login/confirm ``` -

- - -### Headers -

+### Headers ```http Content-Type: application/json ``` -

- - -### Request Body -

- - +### Request Body ```json { "type": "email", @@ -240,11 +178,7 @@ Content-Type: application/json } ``` -

- - -### Response Body -

+### Response Body ```json @@ -260,4 +194,4 @@ Content-Type: application/json "roles": ["User", "Admin"] } } -``` \ No newline at end of file +``` diff --git a/content/docs/developer-docs/rest-apis/authentication/password-authentication/index.mdx b/content/docs/developer-docs/rest-apis/authentication/password-authentication/index.mdx index f5dc17c..938a1c6 100644 --- a/content/docs/developer-docs/rest-apis/authentication/password-authentication/index.mdx +++ b/content/docs/developer-docs/rest-apis/authentication/password-authentication/index.mdx @@ -2,18 +2,15 @@ title: Password icon: "key-round" description: Information about password-based authentication APIs -summary: Comprehensive documentation of SolidX password-based authentication APIs. Covers seven endpoints - Register (with environment variables for enabling registration), Authenticate (login with username and password, returns JWT tokens), Refresh Tokens (obtain new tokens using refresh token), Forgot Password (password reset flow), Change Password (for authenticated users), Get User Info (retrieve current user details), and Logout. Includes HTTP headers, request and response formats, error codes, and security considerations. +summary: Covers register, authenticate, refresh-token, forgot-password, change-password, user-info, and logout endpoints for password-based authentication. --- - -# Password Authentication +## Password Authentication Flow This section covers the password-based authentication APIs available in SolidX. - - -## Implementation Overview +## Implementation Overview SolidX provides a comprehensive password-based authentication mechanism with the following endpoints: @@ -27,22 +24,22 @@ SolidX provides a comprehensive password-based authentication mechanism with the -## 1. Register +## 1. Register Allows users to create a new account. -### Environment Variables +### Environment Variables - `IAM_PASSWORD_REGISTRATION_ENABLED`: Enables/disables registration. - `IAM_ALLOW_PUBLIC_REGISTRATION`: Allows public registration when set to `true`. -### Headers +### Headers ```http Content-Type: application/json ``` -### Request Body +### Request Body ```json { @@ -55,7 +52,7 @@ Allows users to create a new account. } ``` -### Response Body +### Response Body ```json @@ -80,22 +77,22 @@ The response body can be optimized. It currently includes sensitive data like pa -## 2. Authenticate +## 2. Authenticate Log in and receive access and refresh tokens. -### Environment Variables +### Environment Variables - `IAM_JWT_ACCESS_TOKEN_TTL`: TTL for access tokens (default: 60 mins). - `IAM_JWT_REFRESH_TOKEN_TTL`: TTL for refresh tokens (default: 1 day). -### Headers +### Headers ```http Content-Type: application/json ``` -### Request Body +### Request Body ```json { @@ -105,7 +102,7 @@ Content-Type: application/json } ``` -### Response Body +### Response Body ```json { @@ -123,17 +120,17 @@ Content-Type: application/json -## 3. Refresh Tokens +## 3. Refresh Tokens Refresh the access token using a valid refresh token. -### Headers +### Headers ```http Content-Type: application/json ``` -### Request Body +### Request Body ```json { @@ -141,7 +138,7 @@ Content-Type: application/json } ``` -### Response Body +### Response Body ```json { @@ -152,23 +149,23 @@ Content-Type: application/json -## 4. Forgot Password +## 4. Forgot Password Initiates and confirms password reset flow. -### Environment Variables +### Environment Variables - `IAM_OTP_EXPIRY`: OTP expiry time (default: 10 mins). -### Initiate Request +### Initiate Request ```http POST /api/iam/initiate/forgot-password ``` -### Headers +### Headers ```http @@ -199,7 +196,7 @@ Content-Type: application/json } ``` -### Confirm Request +### Confirm Request ```http POST /api/iam/confirm/forgot-password @@ -218,9 +215,9 @@ POST /api/iam/confirm/forgot-password -## 5. Change Password +## 5. Change Password -### Request Body +### Request ```http POST /api/iam/change-password @@ -239,7 +236,7 @@ POST /api/iam/change-password -## 6. Get User Info +## 6. Get User Info Retrieve logged-in user info. diff --git a/content/docs/developer-docs/rest-apis/create/index.md b/content/docs/developer-docs/rest-apis/create/index.mdx similarity index 75% rename from content/docs/developer-docs/rest-apis/create/index.md rename to content/docs/developer-docs/rest-apis/create/index.mdx index 0d1f89d..2be8bb5 100644 --- a/content/docs/developer-docs/rest-apis/create/index.md +++ b/content/docs/developer-docs/rest-apis/create/index.mdx @@ -5,44 +5,26 @@ description: Information about the create endpoint of the REST API, including us summary: This document details the create endpoints in SolidX's REST API, covering single record creation, bulk record creation, and record creation with media files. It provides comprehensive examples including HTTP headers (Content-Type and Authorization), request body structures, and sample responses for each scenario. The create endpoints support both JSON payloads for standard data and multipart/form-data for media uploads. All endpoints require proper create permissions and JWT bearer authentication for security. --- - - - - -# Create Endpoint Overview +## Create Endpoint Overview This section provides information about the SolidX **create REST endpoints**, including how to use them, what parameters they accept, and what responses they return. SolidX supports both single record creation and bulk record creation. +## Creating a Single Record - -## Creating a Single Record - -

- - -### Headers -

+### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -### Request Body -

+### Request Body `POST /api/fee-type` -
- - - Request Body - +#### Request Body ```json { @@ -55,13 +37,7 @@ Authorization: Bearer } ``` -
- -
- - - Sample Request - +#### Sample Request ```json { @@ -71,13 +47,7 @@ Authorization: Bearer } ``` -
- -
- - - Sample Response - +#### Sample Response ```json { @@ -114,27 +84,15 @@ Authorization: Bearer } ``` -
- - - -## Bulk Record Creation +## Bulk Record Creation To create multiple records at once: -

- - -### Request -

+### Request `POST /api/fee-type/bulk` -
- - - Sample Bulk Request - +#### Sample Bulk Request ```json [ @@ -146,20 +104,11 @@ To create multiple records at once: ] ``` -
- - - -## Creating a Record with Media +## Creating a Record with Media If your model includes media fields (e.g., uploading a logo), use the `multipart/form-data` content type. -

- - -### Request with Media -

- +### Request with Media ```http POST /api/fee-type @@ -167,11 +116,7 @@ Content-Type: multipart/form-data Authorization: Bearer ``` -
- - - Multipart Form Data Example - +#### Multipart Form Data Example ```http @@ -191,12 +136,8 @@ Content-Type: image/png --boundary-- ``` -
- - - - + +Ensure the caller has the appropriate **create** permission for the model. Refer to [Permissions](../../../admin-docs/iam/permissions.md) for the access-control side of the flow. - Ensure the user has the appropriate **create permission** for the model. - Refer to the [Permissions](../../../admin-docs/iam/permissions.md) section for more information. + diff --git a/content/docs/developer-docs/rest-apis/delete/index.md b/content/docs/developer-docs/rest-apis/delete/index.mdx similarity index 73% rename from content/docs/developer-docs/rest-apis/delete/index.md rename to content/docs/developer-docs/rest-apis/delete/index.mdx index cff793b..dc01d5c 100644 --- a/content/docs/developer-docs/rest-apis/delete/index.md +++ b/content/docs/developer-docs/rest-apis/delete/index.mdx @@ -5,50 +5,30 @@ description: Information about the delete endpoint of the REST API, including us summary: This document describes the delete endpoints in SolidX's REST API, covering both single record and bulk deletion operations. When soft delete is enabled on a model, records are not permanently removed but marked as deleted with deletedAt and deletedTracker fields populated. The documentation includes detailed examples of delete requests and responses, showing the HTTP headers required (Content-Type and Authorization), endpoint URLs, and the structure of returned data including soft delete metadata and tracking information. --- - -# Delete Endpoint +## Delete Endpoint This section explains how to use the **delete endpoints** of the REST API in SolidX. You can remove records either individually or in bulk using these endpoints. +## Deleting a Single Record +When soft delete is enabled on a model such as `fee-type`, the record is not permanently removed. Instead, the `deletedAt` and `deletedTracker` fields are populated. -## Deleting a Single Record - -When soft delete is enabled on a m Example: Bulk Delete Fee Types -odel (like `fee-type`), the record is not permanently removed - instead, the `deletedAt` and `deletedTracker` fields are populated. - -
- - - Example: Delete a Fee Type Record - - -

- +### Example: Delete a Fee Type Record -### Headers -

+### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -### Request Body -

+### Request ```http DELETE /api/fee-type/{id} ``` -

- - -### Sample Response -

+### Sample Response ```json { @@ -73,59 +53,35 @@ DELETE /api/fee-type/{id} } ``` -
- - The above response confirms soft deletion, showing timestamps and tracker info. - +The response confirms soft deletion and shows the tracking metadata returned by the API. - -## Bulk Deletion +## Bulk Deletion SolidX also supports deleting multiple records in a single request. -
- - - Example: Bulk Delete Fee Types - - +### Example: Bulk Delete Fee Types -

- -### Headers -

+### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -### Request -

+### Request ```http DELETE /api/fee-type/bulk ``` -

- - -### Body -

+### Body ```json [1] // List of record IDs to delete ``` -

- - -### Sample Response -

+### Sample Response ```json [ @@ -152,11 +108,8 @@ DELETE /api/fee-type/bulk ] ``` -
- - +## Summary - **Summary** - Use `DELETE /api/model/{id}` for soft-deleting a single record. - Use `DELETE /api/model/bulk` with an array of IDs for bulk deletion. - Responses return deleted data including soft delete metadata (`deletedAt`, `deletedTracker`). diff --git a/content/docs/developer-docs/rest-apis/index.mdx b/content/docs/developer-docs/rest-apis/index.mdx index 9f9102d..ce231f1 100644 --- a/content/docs/developer-docs/rest-apis/index.mdx +++ b/content/docs/developer-docs/rest-apis/index.mdx @@ -2,19 +2,31 @@ title: REST APIs icon: "globe" description: This section contains details about the SolidX REST APIs serving different functionalities. -summary: This section provides comprehensive documentation of SolidX's auto-generated REST APIs that enable communication between frontend and backend. The APIs cover authentication (password, OTP, OAuth), CRUD operations (create, retrieve, update, delete), record recovery for soft-deleted items, and comprehensive Swagger documentation. Each API endpoint follows RESTful principles with JWT bearer authentication, standardized request/response formats, support for file uploads, filtering, pagination, sorting, and field selection capabilities. +summary: Covers the generated REST API contract in SolidX, including authentication mechanisms, CRUD behavior, recovery endpoints, Swagger inspection, filtering, pagination, and field selection. --- -# Overview +## API Overview - The SolidX REST APIs are the main machine-facing interface of the platform. - - The frontend uses them to communicate with the backend. - - Integrations can use them to automate or extend system behaviour. - - Much of the API surface is generated from metadata and backend structure, then extended where needed. - So the intuition is: the REST API layer is the runtime contract between your metadata-driven backend and the outside world. +The SolidX REST APIs are the primary machine-facing interface of the platform. + +- The frontend consumes them as the default application runtime contract. +- Integrations consume them to automate, synchronize, or extend system behavior. +- A large part of the API surface is generated from metadata and backend structure, then extended where implementation-specific behavior is required. + +The REST API layer is the runtime contract between your metadata-driven backend and external consumers. -This section provides an overview of the SolidX REST APIs, which are designed to facilitate various functionalities within the SolidX framework. These APIs serve as the backbone for communication between the frontend and backend, enabling seamless data exchange and operations. +This section covers authentication, generated CRUD routes, recovery flows, and Swagger-based API inspection. + +## Sections + +- [Authentication](./authentication): Understand how clients authenticate with generated APIs and how bearer-token based access is enforced across the runtime. +- [Create](./create): Review the conventions behind generated create endpoints, request payloads, and write-path behavior for new records. +- [Retrieve](./retrieve): Explore collection and single-record retrieval, including filters, pagination, sorting, field selection, and response semantics. +- [Update](./update): Understand how generated update routes behave for full and partial record updates. +- [Delete](./delete): Review delete semantics, route conventions, and how removal fits into generated CRUD behavior. +- [Recover](./recover): Learn how recovery works for soft-deleted records in projects that enable archival and restore workflows. +- [Swagger Documentation](./swagger-documentation): Use Swagger as the fastest inspection surface for verifying the generated API in a running project. diff --git a/content/docs/developer-docs/rest-apis/recover/index.mdx b/content/docs/developer-docs/rest-apis/recover/index.mdx index 8718821..3a0b240 100644 --- a/content/docs/developer-docs/rest-apis/recover/index.mdx +++ b/content/docs/developer-docs/rest-apis/recover/index.mdx @@ -2,13 +2,11 @@ title: Recover icon: "rotate-ccw" description: Information about the recover endpoint of the REST API, including usage, parameters, and responses -summary: This document explains the recover endpoints in SolidX's REST API, which allow restoration of soft-deleted records. It covers both single record recovery (by ID) and bulk recovery (using an array of IDs) operations. The documentation provides complete examples including HTTP headers, request formats, and sample responses. It also notes a known issue where the response may still contain deletedAt and deletedTracker fields even though the record is successfully recovered in the database, which is expected to be fixed in future releases. +summary: Covers single-record and bulk recovery endpoints, request format, responses, and current behavior for restoring soft-deleted records. --- +## Recover Soft-Deleted Records -# Recover Endpoint - -## Overview The recover endpoint allows you to restore one or more records that have been soft-deleted in your application. This documentation includes usage examples for: @@ -17,37 +15,22 @@ This documentation includes usage examples for: -## Recover a Single Record - -

- +## Recover a Single Record -### Headers -

+### Headers ```http Content-Type: application/json Authorization: Bearer ``` - -

- - -### Sample Request -

- +### Sample Request ```http POST /api/fee-type/recover/{id} ``` - -

- - -### Sample Response -

+### Sample Response ```json { @@ -80,46 +63,28 @@ Although the record is successfully recovered in the database, the response may
+## Bulk Recovery of Records - -## Bulk Recovery of Records - -

- - -### Headers -

+### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -### Sample Request -

+### Sample Request ```http POST /api/fee-type/recover/bulk ``` -

- - -### Sample Body -

+### Sample Body ```json [1, 2, 3] // Array of record IDs to recover ``` -

- - -### Sample Response -

+### Sample Response ```json { diff --git a/content/docs/developer-docs/rest-apis/retrieve/index.md b/content/docs/developer-docs/rest-apis/retrieve/index.mdx similarity index 95% rename from content/docs/developer-docs/rest-apis/retrieve/index.md rename to content/docs/developer-docs/rest-apis/retrieve/index.mdx index dfcb11f..b8a9b9f 100644 --- a/content/docs/developer-docs/rest-apis/retrieve/index.md +++ b/content/docs/developer-docs/rest-apis/retrieve/index.mdx @@ -6,14 +6,12 @@ summary: This document covers the retrieve endpoints of the SolidX REST API, exp solidx_concerns: [frontend.custom_pages, add_full_custom_ui] --- -# Retrieve Endpoints +## Retrieve Endpoints The retrieve endpoints allow you to fetch records from the system. There are two endpoints: -- **Find** - retrieve a list of records with filtering, pagination, sorting, and field selection. -- **FindOne** - retrieve a single record by its ID. - ---- +- **Find** - Retrieve a list of records with filtering, pagination, sorting, and field selection. +- **FindOne** - Retrieve a single record by its ID. ## Find (List Records) @@ -59,8 +57,6 @@ GET /api/persons?limit=10&offset=0&fields[0]=id&fields[1]=name&fields[2]=email&p } ``` ---- - ## FindOne (Single Record) Returns a single record by its ID. @@ -98,8 +94,6 @@ GET /api/persons/12?populate[0]=department&populate[1]=manager&populateMedia[0]= } ``` ---- - ## Filtering Both the **Find** endpoint and the backend [CRUD Service `find()` method](../../extending/backend-customization/crud-service#4-findfilterdto-context) share the same filter syntax and operators. diff --git a/content/docs/developer-docs/rest-apis/swagger-documentation/index.mdx b/content/docs/developer-docs/rest-apis/swagger-documentation/index.mdx index 47263bb..5e5ffa5 100644 --- a/content/docs/developer-docs/rest-apis/swagger-documentation/index.mdx +++ b/content/docs/developer-docs/rest-apis/swagger-documentation/index.mdx @@ -2,31 +2,51 @@ title: Swagger icon: "book-open" description: This section provides details on how to access and use the Swagger documentation for SolidX REST APIs. -summary: This document provides comprehensive information about accessing and using SolidX's auto-generated Swagger/OpenAPI documentation. It explains how to access the documentation at the /api/docs endpoint, authenticate using JWT tokens via the login endpoint, and utilize the standard RESTful endpoints automatically generated for each resource. The documentation covers query parameters for filtering, sorting, pagination, population, and field selection, provides example requests for common operations, explains the standardized error handling format with common HTTP status codes, and outlines best practices for authentication, request optimization, error handling, and API documentation maintenance. +summary: Explains how to access the generated Swagger documentation, authenticate requests, inspect endpoints, and work with common query parameters and error responses. --- -import { Shield, Zap, AlertTriangle, BookOpen } from 'lucide-react'; +## Swagger Explorer -# API Documentation +SolidX automatically generates API documentation for your endpoints using Swagger and the OpenAPI specification. Swagger UI gives developers an interactive surface to inspect routes, payloads, and auth-protected requests without leaving the browser. -SOLID automatically generates comprehensive API documentation for all your endpoints using Swagger/OpenAPI specification. This documentation provides developers with an interactive interface to explore and test the APIs. + -## Accessing API Documentation +Swagger is the fastest way to inspect what the current backend actually exposes. Treat it as a live contract viewer for generated and extended endpoints, not just a passive reference page. + + -To access the Swagger documentation: +## Accessing API Documentation -1. Navigate to your SOLID installation -2. Go to `/api/docs` endpoint -3. You'll see the Swagger UI with all available endpoints + + + Navigate to your SolidX installation. + + + Go to the `/docs` endpoint of your `solid api` runtime. + + + You will see the Swagger UI with all available endpoints. + + ## Authentication Before using the APIs, you'll need to authenticate: -1. Use the `/api/auth/login` endpoint -2. Provide your credentials -3. Receive a JWT token -4. Use this token in the Authorization header for subsequent requests + + + Use the `/api/iam/authenticate` endpoint. + + + Provide your credentials. + + + Receive a JWT token in form of access token. + + + Use this token in the Authorization header for subsequent requests. + + ### Example Authentication Flow @@ -64,6 +84,7 @@ Each resource in your SOLID app automatically gets the following RESTful endpoin | GET | `/api/{resource}/{id}` | Get single resource | | POST | `/api/{resource}` | Create resource | | PUT | `/api/{resource}/{id}` | Update resource | +| PATCH | `/api/{resource}/{id}` | Partially update resource | | DELETE | `/api/{resource}/{id}` | Delete resource | ### Query Parameters @@ -138,29 +159,7 @@ All API errors follow a consistent format: ## Best Practices - - } title="Authentication"> - - Always use HTTPS - - Keep tokens secure - - Implement token refresh - - Handle token expiration - - } title="Request Optimization"> - - Use field selection - - Implement pagination - - Optimize queries - - Cache responses - - } title="Error Handling"> - - Validate input data - - Return meaningful errors - - Log API errors - - Handle rate limiting - - } title="Documentation"> - - Keep examples up-to-date - - Document all parameters - - Include response examples - - Note any limitations - - +- **Authentication**: Use HTTPS, keep tokens secure, and verify protected routes with a real bearer token before testing downstream APIs. +- **Request Optimization**: Use field selection, pagination, relation population, and filter parameters deliberately so large resources stay easy to inspect. +- **Error Handling**: Use Swagger to validate request shape, inspect error payloads, and confirm that status codes match the intended runtime behavior. +- **Documentation**: Keep examples aligned with real payloads and use the live docs as the quickest checkpoint after metadata or backend extension changes. diff --git a/content/docs/developer-docs/rest-apis/update/index.md b/content/docs/developer-docs/rest-apis/update/index.mdx similarity index 76% rename from content/docs/developer-docs/rest-apis/update/index.md rename to content/docs/developer-docs/rest-apis/update/index.mdx index 916272a..ddcbb4a 100644 --- a/content/docs/developer-docs/rest-apis/update/index.md +++ b/content/docs/developer-docs/rest-apis/update/index.mdx @@ -5,51 +5,32 @@ description: Information about the update endpoints of the REST API, including u summary: This document explains the update endpoints in SolidX's REST API, covering both partial updates (PATCH method for updating specific fields) and full updates (PUT method for replacing entire records). It provides detailed examples of updates without media files (using JSON content type) and updates with media files (using multipart/form-data). Each section includes HTTP headers, request formats, sample payloads, and response structures. Both update methods are idempotent and require JWT bearer authentication. --- - -# Update Endpoints in SolidX +## Update Endpoints in SolidX This section provides details about the **Update Endpoints** of the REST API, including usage patterns, headers, request/response formats, and examples of both **partial** and **full** updates. +## Types of Updates - -## Types of Updates - -### 1 Partial Update +### 1. Partial Update - Method: `PATCH` - Purpose: Update specific fields of a record without affecting the rest. -
- - - Example: Update feeType Field - +### Example: Update `feeType` Field -

- - -#### Headers -

+#### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -#### Request -

+#### Request ```http PATCH /api/fee-type/1 ``` -

- - -#### Body -

+#### Body ```json { @@ -60,11 +41,7 @@ PATCH /api/fee-type/1 -

- - -#### Response -

+#### Response ```json { @@ -86,47 +63,27 @@ PATCH /api/fee-type/1 } ``` -
- - - -### 2 Full Update +### 2. Full Update - Method: `PUT` - Purpose: Replace the entire model with a new object. - Idempotent: Yes (repeated calls with the same payload have the same effect). -
- - - Example: Full Update of Fee Type - - -

- +### Example: Full Update of Fee Type -#### Headers -

+#### Headers ```http Content-Type: application/json Authorization: Bearer ``` -

- - -#### Request -

+#### Request ```http PUT /api/fee-type/1 ``` -

- - -#### Body -

+#### Body ```json { @@ -136,11 +93,7 @@ PUT /api/fee-type/1 } ``` -

- - -#### Response -

+#### Response ```json { @@ -164,19 +117,11 @@ PUT /api/fee-type/1 } ``` -
- - - -## Update Without Media +## Update Without Media Used when no files (like images or documents) are uploaded. -
- - - Example: JSON-only Update - +### Example: JSON-only Update ```http @@ -192,19 +137,11 @@ Authorization: Bearer } ``` -
- - - -## Update With Media +## Update With Media Used when the request includes file uploads (e.g., profile pictures, attachments). -
- - - Example: Update with Multipart Form Data - +### Example: Update with Multipart Form Data ```http PATCH /api/institute-user/1 @@ -224,7 +161,3 @@ updateDto: { } files: profile-picture.jpg ``` - -
- - diff --git a/content/docs/developer-docs/solidctl-commands.mdx b/content/docs/developer-docs/solidctl-commands.mdx index 7ffbe16..04710d5 100644 --- a/content/docs/developer-docs/solidctl-commands.mdx +++ b/content/docs/developer-docs/solidctl-commands.mdx @@ -4,19 +4,21 @@ icon: "terminal" description: Reference for the SolidX CLI (`solidctl`) used to scaffold, build, upgrade, inspect, seed, test, generate, and run agent tasks in a SolidX project. --- -# solidctl Reference +## CLI Overview The `solidctl` CLI is the main command-line entry point for working with SolidX projects. - Think of solidctl as the operational control surface for a SolidX project. - - Bootstrap commands create and build the project. - - Platform commands seed metadata and inspect project state. - - Development commands regenerate code and update package versions. - - Testing commands prepare isolated test environments and run scenarios. - - Agent commands run the SolidX AI agent. - So the intuition is: solidctl is not just a scaffolding command. It is the main CLI you use across the entire lifecycle of a SolidX app, from project creation to testing and maintenance. +`solidctl` is the operational control surface for a SolidX project. + +- `Bootstrap commands` create and build the project. +- `Platform commands` seed metadata and inspect project state. +- `Development commands` regenerate code and update package versions. +- `Testing commands` prepare isolated test environments and run scenarios. +- `Agent commands` run the SolidX AI agent. + +It is not limited to scaffolding. It is the primary CLI used across project creation, platform maintenance, code generation, testing, and upgrade workflows. @@ -241,9 +243,9 @@ solidctl seed [options] ### When to use it -- after initial project setup -- after changing metadata JSON files -- after upgrades that introduce new platform metadata +- After initial project setup +- After changing metadata JSON files +- After upgrades that introduce new platform metadata ### Examples diff --git a/content/docs/quick-start/index.mdx b/content/docs/quick-start/index.mdx index dba94eb..8082597 100644 --- a/content/docs/quick-start/index.mdx +++ b/content/docs/quick-start/index.mdx @@ -12,9 +12,9 @@ summary: "Two paths to a working SolidX project. Manual mode walks you through e | **Node.js** | 22+ (LTS recommended) | All modes | `node -v` | | **Docker** | Latest stable | *Optional* - only if you choose a full external PostgreSQL server instead of the embedded database | `docker --version` | | **PostgreSQL** | 14+ | *Optional* - only if you connect to an existing external PostgreSQL instance instead of the embedded database | `psql --version` | -| **Python** | 3.11+ | Agent & MCP only | `python3 --version` | +| **Python** | 3.12+ | Agent & MCP only | `python --version` | -Node.js is the only hard requirement. The default embedded path needs nothing else. Docker or PostgreSQL are only needed if you choose the full PostgreSQL path in Step 2. Python is only needed if you plan to use the [SolidX AI Agent](/docs/quick-start/using-solidx-ai-agent) or [MCP server](/docs/quick-start/using-solidx-mcp-server). +Node.js is the only hard requirement. The default embedded path needs nothing else. Docker or PostgreSQL are only needed if you choose the full PostgreSQL path in Step 2. Python is only needed if you plan to use the [SolidX AI Agent](/docs/quick-start/using-solidx-ai-agent) or [MCP server](/docs/quick-start/using-solidx-mcp-server), because both runtimes are Python-based. diff --git a/content/docs/quick-start/using-solidx-ai-agent.mdx b/content/docs/quick-start/using-solidx-ai-agent.mdx index ab9cbe9..9c0cd3e 100644 --- a/content/docs/quick-start/using-solidx-ai-agent.mdx +++ b/content/docs/quick-start/using-solidx-ai-agent.mdx @@ -17,7 +17,7 @@ This guide assumes you have already scaffolded and started a SolidX project usin -The SolidX AI agent requires **Python 3.11+**. Verify with `python3 --version`. On first run, `solidctl agent start` auto-installs the agent's Python package into `~/.solidx/venv` if `solidx-agent` is not already in PATH. +The SolidX AI agent requires **Python 3.12+**. Verify with `python --version`. Python is required because the SolidX agent runtime is Python-based. On first run, `solidctl agent start` auto-installs the agent's Python package into `~/.solidx/venv` if `solidx-agent` is not already in PATH.