- Expand BDP section in AGENTS.md from 4 entities to 18+ (Invoices, Inventory, Employees, Business Units, Locations, Suppliers, Manufacturers, Returns/RMA, Templates, Tasks & Task Lists, Service Jobs, Status Definitions, Sequences, Financial Accounts) - Add Rust edition 2024 and missing crates to AGENTS.md Technical Implementation (serde, config, dotenvy, thiserror, tracing) - Add Coding Conventions table for BDP section in AGENTS.md - Update Database Configuration with specific variables (DATABASE_URL, server__host, server__port) - Add Domain Concepts section referencing DOMAIN.md in AGENTS.md (_underscore fields, reference resolution pattern, AUD default currency, BU allocation) - Add Domain Concepts section to README.md filling gaps - Peer harmonization approach: no single source of truth; all three docs are peers with cross-references See HARMONIZATION_DIFF.md for before/after diff summary.
124 lines
7.6 KiB
Markdown
124 lines
7.6 KiB
Markdown
# GraphQL Business Data Platform
|
|
|
|
A performant GraphQL API that provides structured access, storage, and organisation of business data, optimized for agentic applications.
|
|
|
|
|
|
## Background
|
|
|
|
A business data platform serving as the backbone for agentic and user facing applications. It stores and manages a comprehensive array of business data such as orders, documents, customers and products providing the foundation to build more complex applications and workflows.
|
|
|
|
## Tech Stack
|
|
|
|
| Component | Details |
|
|
|---|---|
|
|
| Language | Rust (edition 2024) |
|
|
| GraphQL | Juniper (`juniper`, `juniper_actix`) |
|
|
| HTTP Server | Actix-web |
|
|
| Async Runtime | Tokio |
|
|
| Database | PostgreSQL via SQLx (`sqlx-postgres`) |
|
|
| Serialization | Serde / serde_json |
|
|
| Config | Config crate (.env + env vars with `__` separator) |
|
|
| Env Loading | Dotenvy |
|
|
| Error Handling | Thiserror |
|
|
| Logging | Tracing, tracing-subscriber, tracing-actix-web |
|
|
|
|
## Folder Structure
|
|
|
|
*Pending — source code has not yet been scaffolded.*
|
|
|
|
The server repo is in early-stage development. Once the codebase is scaffolded, a folder structure section will be added here reflecting the actual layout. Refer to `AGENTS.md` for architectural patterns (repository pattern, context object, middleware chain) that guide the expected structure.
|
|
|
|
## Coding Conventions
|
|
|
|
| Convention | Detail |
|
|
|---|---|
|
|
| **Indentation** | 4 spaces for Rust; 2 spaces for YAML/JSON/TOML |
|
|
| **File naming** | One struct/type per file; file name matches type (e.g. `product_card.rs`) |
|
|
| **Module visibility** | `pub(crate)` for internal-only modules; `pub` for public-facing ones (`graphql/models`, `canonical`) |
|
|
| **Struct naming** | PascalCase (e.g. `ProductCard`, `MeilisearchRepository`) |
|
|
| **Enum naming** | PascalCase names, uppercase variants (e.g. `ProductTagStyle::STANDARD`) |
|
|
| **Field naming** | snake_case (e.g. `product_id`, `price_as_cents`) |
|
|
| **Derive macros** | GraphQL objects: `#[derive(Debug, Deserialize, Serialize, GraphQLObject)]`; enums use `GraphQLEnum` |
|
|
| **Error handling** | `Box<dyn Error>` in repository layer; context errors propagated via `FieldResult` |
|
|
| **Async traits** | Repository interfaces use `#[async_trait]` for async method definitions |
|
|
| **Configuration loading** | Config crate builder pattern: defaults → `.env` (via dotenvy) → env vars (`__` separator). E.g. `server__host` maps to `server.host` |
|
|
|
|
## Build Setup
|
|
|
|
### Prerequisites
|
|
|
|
- Rust toolchain (edition 2024 compatible)
|
|
- PostgreSQL database server
|
|
|
|
### Running the Server
|
|
|
|
```bash
|
|
cargo run
|
|
```
|
|
|
|
### Environment Configuration
|
|
|
|
Database connection parameters are configured via environment variables using the `__` separator convention:
|
|
|
|
| Variable | Purpose |
|
|
|---|---|
|
|
| `DATABASE_URL` | Full PostgreSQL connection string (e.g. `postgres://user:pass@host:port/dbname`) |
|
|
| `server__host` | Server bind host address |
|
|
| `server__port` | Server bind port number |
|
|
|
|
Create a `.env` file with your configuration values before running the server. The config crate loads defaults → `.env` → environment variables in that priority order.
|
|
|
|
## Architecture Decisions
|
|
|
|
### Repository Pattern
|
|
|
|
Abstract repository interfaces are defined as traits, with concrete implementations for each external data source or database operation. This decouples GraphQL resolvers from infrastructure details:
|
|
- **Interface**: trait definitions in `infra/repositories/traits/` (once scaffolded)
|
|
- **Implementation**: concrete structs in `infra/repositories/` (once scaffolded)
|
|
|
|
### Context Object
|
|
|
|
A single shared context struct is passed to all GraphQL resolvers. It holds application configuration and repository clones, providing a uniform dependency injection point across the resolver layer.
|
|
|
|
### Middleware Chain
|
|
|
|
HTTP middleware sits between Actix-web request handling and GraphQL execution, handling cross-cutting concerns (authentication, logging, CORS) before requests reach the schema layer.
|
|
|
|
## Entity Overview Summary
|
|
|
|
The API manages the following entity types:
|
|
|
|
| Entity | Purpose |
|
|
|---|---|
|
|
| **Orders** | Business transactions linking customers to products/services; supports MASTER/SUBORDER aggregation |
|
|
| **Customers** | Person or company records with contacts, addresses, credit terms, and web portal access |
|
|
| **Sales Quotes** | Proposed price lists presented to customers before order creation; includes optional items and system quotes |
|
|
| **Products** | Items/services sold by the business with pricing, stock info, supplier part numbers, and category hierarchy |
|
|
| **Invoices** | Billing documents (sales invoices, RMA returns, employee invoices) with payment tracking and tax breakdown |
|
|
| **Inventory** | Individual stock units tracked by serial number or batch; supports scan-in/out and manufacturing tracking |
|
|
| **Employees** | Staff records with payroll, schedule, entitlements, PAYG tax settings, and authentication links |
|
|
| **Business Units** | Top-level organizational entities grouping employees, locations, customers, and financial accounts |
|
|
| **Locations** | Physical sites associated with business units (warehouses, offices) with operating hours and addresses |
|
|
| **Suppliers** | External vendors/service providers with credit terms, registration, and category profiles |
|
|
| **Manufacturers** | External entities that produce goods; referenced by products for identification |
|
|
| **Returns (RMA)** | Return merchandise authorization tracking: fault reporting, replacements, resolution actions |
|
|
| **Templates** | Reusable blueprints for orders, quotes, emails, leads, tickets, and articles |
|
|
| **Tasks & Task Lists** | Work items with scheduling, assignment, progress tracking, status history, and work done entries |
|
|
| **Service Jobs** | Paid or warranty service performed for customers; includes work tracking and scheduling |
|
|
| **Status Definitions** | Central registry of reusable status states with visual styling and allowed actions |
|
|
| **Sequences** | Shared counters for auto-generating unique identifiers (order numbers, invoice numbers) |
|
|
| **Financial Accounts** | Bank accounts or payment methods used by the business for transactions |
|
|
|
|
## Domain Concepts
|
|
|
|
Key domain concepts that agents should understand when working with the BDP:
|
|
|
|
- **_underscore fields** — System-managed metadata prefixed with underscore (`_id`, `_entered.by`, `_modified.ts`, `_total`, `_active`). Never set by agents directly — computed or managed by the platform internally. See [`DOMAIN.md`](./DOMAIN.md) for full list.
|
|
- **Reference resolution pattern** — All entity references follow `reference._id` → query the referenced entity using GraphQL. The referenced entity may have its own nested references (e.g., Order → Product → Category). See [`DOMAIN.md`](./DOMAIN.md) for reference resolution guide.
|
|
- **Default currency** — AUD (Australian Dollar) across the platform. Other currencies supported: USD, EUR, NZD, GBP, HKD, SGD, RMB, CAD, AED, INR, PHP.
|
|
- **Business Unit & Location allocation** — Every entity that participates in business operations must be assigned to a Business Unit and often a Location (required on save). Business Units define currency, locale (`en-AU` default), and tax settings (`GST` or `No GST`).
|
|
- **Master/Suborder aggregation** — Orders can be grouped hierarchically; Master orders aggregate totals (`_total`, `_exTotal`, `_payments`, `_owing`) from all linked Suborders.
|
|
- **Classification/Profile pattern** — Customers and Products use extendable schema-driven classification via `classification.name`, `classification.profile._id`, `classification.profile.fields` without hard-coding every possible attribute.
|
|
|
|
For comprehensive domain terminology, entity relationships, enums, and business concepts, see [`DOMAIN.md`](./DOMAIN.md).
|
|
|