Technical Overview
1. Introduction
DMART (Data Mart) is a Data-as-a-Service (DaaS) platform designed to act as a streamlined, low-code information inventory system. It treats data assets as commodities, allowing for structured, unstructured, and binary data management. Optimized for small to medium data footprints (<=300 million primary entries), it uses a SQL database for data longevity and ACID compliance.
2. Architecture
DMART follows a microservices-friendly architecture with clear separation between the API layer, data processing, and storage.
graph TD
User["User / Client"] -->|"HTTP/REST"| LB["Load Balancer / Reverse Proxy"]
LB -->|HTTP| API["ASP.NET Core (Kestrel)"]
subgraph "Backend (AOT binary)"
API -->|RW| SQL["PostgreSQL (Npgsql)"]
API -->|"MCP /mcp"| MCP["MCP Server"]
end
subgraph "Embedded Frontend"
CXB["CXB (/cxb)"] -->|"API Calls"| API
CAT["Catalog (/cat)"] -->|"API Calls"| API
end
SQL -->|"Export (zip)"| Backup["Backup / Import-Export"]
Backend Stack
Language & Runtime: C# on .NET 10, compiled ahead of time with Native AOT into a single self-contained binary (~50 MB; 46 MB arm64, 53 MB x64) — no runtime install required. JSON is source-generated (System.Text.Json), and the same binary bundles both the server and the CLI client.
Web Framework: ASP.NET Core Minimal APIs on the Kestrel HTTP server, built with the slim/AOT host (
WebApplication.CreateSlimBuilder). Endpoints are route groups (MapGroup), not MVC controllers. Swagger/OpenAPI is served at/docs.Data Persistence: PostgreSQL (via Npgsql) is the single source of truth for all runtime data — ACID compliant with relational integrity. There is no Redis and no filesystem runtime store; caches are in-process only.
Authentication: JWT Bearer (HS256, Argon2-hashed passwords), plus a full OAuth 2.1 Authorization Server with Google, Facebook, and Apple sign-in.
Interoperability: Built-in MCP server at
/mcp(Streamable HTTP; off by default, enable withENABLE_MCP=true) and WebSocket endpoints for realtime updates.
Frontend Stack
DMART ships two Svelte 5 + Vite admin SPAs that are embedded directly into the .NET binary and served by ASP.NET middleware — no separate frontend deployment:
CXB (
/cxb): the Customer eXperience Builder — the primary administrative interface.Catalog (
/cat): a user-oriented SPA.Under the hood: Svelte 5, @roxi/routify v3, Vite, and Svelte stores for state.
3. Data Model
DMART uses an Entry-oriented data model rather than a document-oriented one. All entities inherit from a base Meta class.
Resource Hierarchy
Space: Top-level container defining configuration like languages, plugins, and visibility.
Subpath: Logical folder structure within a space (e.g.,
/content/posts).Entry: Atomic unit of information with UUID, Shortname, Meta, Payload, and Attachments.
Key Data Structures
Meta: Base class (uuid, shortname, slug, acl, etc.).
Record: Flat representation for API I/O.
Payload: Content type, schema reference, and body.
Attachment: Extends Meta for attached resources. Subtypes: Media, Comment, Reaction, Relationship.
DataAsset: Specialized attachments for tabular/binary data files — supported content types are CSV, JSONL, SQLite, and Parquet. Here
sqliteis only a data-asset content type, never the database backend (the backend is always PostgreSQL).Ticket: Extends Meta for workflow states, reporters, and collaborators.
classDiagram
class Resource {
<<abstract>>
}
class Payload {
+ContentType ContentType
+string Body
}
class Meta {
+Guid Uuid
+string Shortname
+Translation Displayname
+Payload Payload
}
Resource <|-- Payload
Resource <|-- Meta
Meta <|-- Space
Meta <|-- Actor
Meta <|-- Group
Meta <|-- Content
Meta <|-- Schema
Meta <|-- Attachment
Meta <|-- Ticket
Actor <|-- User
Attachment <|-- DataAsset
Attachment <|-- Comment
DataAsset <|-- Csv
DataAsset <|-- Jsonl
DataAsset <|-- Sqlite
DataAsset <|-- Parquet
4. Key Features
4.1 Storage & Data Longevity
Data is stored in normalized PostgreSQL tables, ensuring ACID compliance and standard relational integrity. PostgreSQL is the sole runtime store; the on-disk spaces/ + .dm/ layout is used only as a portable import/export, seed, and migration format (zip round-trips), never as a live data store.
4.2 Advanced Search & Querying
The /query endpoint supports a rich query language that is compiled to SQL. Search runs on PostgreSQL with trigram indexes (pg_trgm + GIN on jsonb), with optional pgvector semantic search for cosine-similarity matching:
Filtering: By space, subpath, resource type, schema, and specific shortnames.
Full-text Search: Fuzzy matching on text fields.
Aggregation: Grouping and reducing data (counts, sums).
Sorting & Pagination:
limit,offset,sort_by.Specialized Queries:
history,events,tags,reports.
4.3 Access Control (RBAC + ACL)
Security enforced via a comprehensive AccessControl module:
Permission Scope: Action type, subpath, resource type, conditions, field-level restrictions.
ACLs: Per-instance access overrides on individual entries.
4.4 Workflows & Tickets
Ticketing system with state management and a /progress-ticket API for workflow transitions.
4.5 Data Import/Export
ZIP: Full space export/import preserving folder structure.
CSV Export: Stream query results as CSV (
/csvendpoint).CSV Import: Batch-create resources from CSV uploads (
/resources_from_csv).
4.6 Plugin System
Event-driven plugin architecture built around two C# interfaces: IApiPlugin (new endpoints mounted at /{shortname}) and IHookPlugin (before/after action interceptors). Beyond managed C# plugins, DMART also loads native plugins from ~/.dmart/plugins — either crash-safe subprocess executables (JSON-lines over stdin/stdout) or shared libraries via a C ABI — enabling extensions written in any language.
Request Flow
sequenceDiagram
participant Client
participant Middleware
participant Router
participant AccessControl
participant PluginManager
participant SqlAdapter
Client->>Middleware: HTTP Request (Kestrel)
Middleware->>Middleware: JWT Auth & Logging
Middleware->>Router: Route Request (Minimal API)
Router->>AccessControl: Check Permissions (RBAC/ACL)
alt Access Denied
AccessControl-->>Client: 403 Forbidden
else Access Granted
Router->>PluginManager: Trigger Before Hooks
PluginManager->>PluginManager: Run IHookPlugin handlers
Router->>SqlAdapter: Perform Action (CRUD)
SqlAdapter->>SqlAdapter: Persist to PostgreSQL & Index
Router->>PluginManager: Trigger After Hooks
PluginManager->>PluginManager: Run async side effects (Task)
Router-->>Client: HTTP Response
end
5. API Structure
REST-like and resource-oriented. Key routers:
/managed: Core content management (CRUD, Query, Import/Export).
/request: Unified endpoint for batch operations./query: Main search endpoint./entry: Single entry metadata and payload./payload: Raw content/media retrieval./import//export: Bulk data operations./user: Authentication and profile management./public: Read-only access for public content./qr: QR code generation./info: System information and manifest./mcp: Model Context Protocol server (Streamable HTTP) exposing DMART tools to AI clients, paired with the OAuth 2.1 Authorization Server for client onboarding. RequiresENABLE_MCP=true; off by default./docs: Swagger UI and OpenAPI schema (/docs/openapi.json).
6. Data Asset Management
DMART natively handles analytical data files:
Specialized support for SQLite attachments — perform SQL queries directly on attached files via the API. Note that
sqlitehere is a data-asset content type only, not the database backend (the backend is always PostgreSQL).Parquet, JSONL, and CSV are treated as first-class data citizens.
7. Deployment
Single Binary: Native-AOT publish produces one self-contained
dmartexecutable (~50 MB) with no runtime dependency — copy and run. The embedded admin UIs and sample seed data ship inside it, and the same binary doubles as the CLI (seed,import,export,migrate).Containerized: Docker/Podman images available (
ghcr.io/edraj/csdmart).Config: Environment variables /
config.env, bound and validated once at startup (strict unknown-key rejection, no hot reload).External dependency: a PostgreSQL instance — no Redis, no separate search cluster required.