Milesoft Primitives Library (primitives)

1. Overview & Purpose

The primitives library is the Tier-0 contract layer of the Milesoft platform. It provides foundational types, constants, multi-tenant ownership contracts, programmatic validation interfaces, and utility classes used by all Milesoft services and external Software Development Kits (SDKs).

1.1 Strategic Architecture: Zero-Dependency Policy

Because primitives is the ultimate root of the Milesoft dependency tree, it adheres to a strict zero external runtime dependencies policy:

  • Strict Insulation: It is compiled using only lightweight standard JDK features and compileOnly annotations (such as Lombok and Jakarta Bean Validation).
  • No Classpath Leakage: Downstream applications consuming our SDKs will experience a completely clean compile and runtime classpath, shielding them from transitive library bloat and classpath resolution conflicts.
  • Optimized Performance: All parsers and structures (e.g., semantic version parsing) are implemented using pure, highly optimized Java logic.

2. Installation & Status

To resolve this package from our secure Google Cloud Artifact Registry repository, configure your build.gradle as follows:

repositories {
    mavenCentral()
    maven { url "artifactregistry://us-west2-maven.pkg.dev/milesoft-repo/repo-maven" }
}

dependencies {
    // For shared libraries and SDKs, declare as an api dependency
    api "io.milesoft:primitives:2.0.1"
    
    // For standalone microservices and applications
    implementation "io.milesoft:primitives:2.0.1"
}

2.1 Status

The primitives library is Production-Ready and fully integrated across the Milesoft ecosystem.


3. Core Modules & Usage Examples

3.1 Core Multi-Tenant Context (io.milesoft.primitives.actor)

The Actor record is the primary security calling context representation within the platform. It encapsulates the active application, subscriber account (tenant), and user profile executing the current request.

  • Strict Validations: All fields (appId, accountId, userId) must be non-null and non-blank upon record instantiation.
  • Fluent Wither Methods: It provides fluent builder-like methods (withApp, withAccount, withUser, etc.) that return new Actor records with updated attributes.
  • Unknown Identifiers: Includes predefined constants representing unauthenticated or unknown actors.
import io.milesoft.primitives.actor.Actor;

// Instantiating a tenant-specific actor
Actor actor = Actor.of("app-123", "account-456");

// Fluent transformation to attach user identity
Actor fullyQualifiedActor = actor.withUser("user-789");

System.out.println(fullyQualifiedActor.appId());     // "app-123"
System.out.println(fullyQualifiedActor.accountId()); // "account-456"
System.out.println(fullyQualifiedActor.userId());    // "user-789"

3.2 Semantic Versioning & Artifact Key Identification (io.milesoft.primitives.artifact)

Handles robust verification and comparison of platform software artifacts, services, and dynamic assets.

  • Version: Represents standard semantic versions (major.minor.patch). Supports strict parsing and verification (each numeric component is restricted to 0-9999).
    • Lexicographical Padding (toPaddedString): Zero-pads version tokens into a 0000.0000.0000 representation (e.g., 1.12.3 becomes 0001.0012.0003), enabling immediate, clean lexicographical sorting in database queries.
    • Comparison Utilities: Implements standard Comparable alongside helper methods before(Version) and after(Version).
  • ArtifactKey: Uniquely represents developers' platform libraries or dynamic models using a developerId, artifactId, and a Version.
    • Version Elision: If the Version is null, the artifact defaults to latest.
    • Comparison Safety (equalsIgnoreVersion): Allows comparing artifact coordinates while ignoring current version variations.
import io.milesoft.primitives.artifact.Version;
import io.milesoft.primitives.artifact.ArtifactKey;

// Parse semver indicators
Version v1 = Version.of("1.10.2");
Version v2 = Version.of("2.0.0");

if (v2.after(v1)) {
    System.out.println("v2 is newer!");
}

// Generate padded representation for sorting
System.out.println(v1.toPaddedString()); // "0001.0010.0002"

// Construct artifact keys
ArtifactKey key = ArtifactKey.of("milesoft", "auth-utils");
System.out.println(key); // milesoft:auth-utils:latest

3.3 Programmatic Self-Validation (io.milesoft.primitives.validation)

Allows implementing custom, multi-field programmatic validation checks directly inside Data Transfer Objects (DTOs) and payload representations. It leverages Jakarta validation standards without compiling against complex, framework-specific libraries.

  • @SelfValidated: Class-level JSR-380 (Jakarta Bean Validation) constraint annotation.
  • SelfValidating: Interface requiring the implementation of a single method: boolean isValid(ConstraintValidatorContext context).
import io.milesoft.primitives.validation.SelfValidated;
import io.milesoft.primitives.validation.SelfValidating;
import jakarta.validation.ConstraintValidatorContext;
import java.time.LocalDate;

@SelfValidated(message = "End date must be chronologically after the start date")
public class DateRange implements SelfValidating {

    private LocalDate startDate;
    private LocalDate endDate;

    @Override
    public boolean isValid(ConstraintValidatorContext context) {
        if (startDate == null || endDate == null) {
            return true; // Return true here and use standard @NotNull constraints for null-checking
        }
        return endDate.isAfter(startDate);
    }
}

3.4 Multi-Tenant Ownership Contracts (io.milesoft.primitives.tenant)

A suite of structural interfaces implemented by domain models, JPA entities, and API payloads to guarantee standardized, compiler-verified multi-tenant data structures.

The following ownership contracts are available:

Interface Method Signature Primary Use Case
OwnedByApp String getAppId() App-specific configs, branding, or feature flags.
OwnedByApps Collection<String> getAppIds() Resources shared across specific system applications.
OwnedByAccount String getAccountId() Subscriber tenant-specific transactions, metadata, and files.
OwnedByAccounts Collection<String> getAccountIds() Broad data access spanning multi-tenant consortia.
OwnedByUser String getUserId() Personal preferences, individual file uploads, or private messages.
OwnedByUsers Collection<String> getUserIds() Group chats or shared team collaborations.
OwnedByAccountUser String getAccountId()
String getUserId()
Tenant-bound user profiles, timesheets, and activity logs.
OwnedByAppAccountUser String getAppId()
String getAccountId()
String getUserId()
High-specificity audit trails, session nonces, and access configurations.
import io.milesoft.primitives.tenant.OwnedByAccount;

public class SubscriberAsset implements OwnedByAccount {
    
    private String accountId;
    private String assetName;

    @Override
    public String getAccountId() {
        return this.accountId;
    }
}

3.5 Token Provider Security Abstraction (io.milesoft.primitives.security)

A functional interface used by downstream SDK base clients to retrieve HTTP authorization headers dynamically. This decouples client implementations from specific HTTP libraries, Spring security contexts, or credentials storage.

  • Method: String getAuth(Actor actor, boolean fresh)
  • Dynamic Renewal: Downstream SDK clients can supply the fresh = true flag to automatically force login renewals upon receiving 401 Unauthorized responses.
import io.milesoft.primitives.security.TokenProvider;

// Lambda definition for a static API key token provider
TokenProvider staticProvider = (actor, fresh) -> "Bearer platform-api-key-xyz";

3.6 Temporal Payload Wrapper (io.milesoft.primitives.temporal)

  • Timestamped<I>: Generic container class that couples any payload I with an immutable ZonedDateTime timestamp. Both values are strictly verified as non-null upon construction.
  • Highly useful for telemetry records, state histories, event-sourcing events, and audits.
import io.milesoft.primitives.temporal.Timestamped;
import java.time.ZonedDateTime;

Timestamped<String> logEntry = new Timestamped<>("Process Initiated", ZonedDateTime.now());
System.out.println(logEntry.getItem());      // "Process Initiated"
System.out.println(logEntry.getTimestamp()); // Timezone-aware timestamp

3.7 Standardized API Observability Exceptions (io.milesoft.primitives.exception)

Core error models that standardize observability and error structures across the platform.

  • ApiError: Canonical REST error response payload returned by all backend microservices. Supports fields for error codes, HTTP status, timestamp, and field-level validation errors.
  • ClientResponseException: Decoupled runtime exception thrown by SDK clients when an HTTP request fails (returns non-2xx status). It bypasses framework dependencies (such as Spring WebClient exceptions), keeping classpaths completely clean.
import io.milesoft.primitives.exception.ClientResponseException;
import io.milesoft.primitives.exception.ApiError;

try {
    userClient.updateProfile(actor, saveDto);
} catch (ClientResponseException ex) {
    System.out.println("HTTP Status Code: " + ex.getStatusCode());
    
    ApiError errorPayload = ex.getApiError();
    if (errorPayload != null) {
        System.out.println("Platform Error Code: " + errorPayload.getErrorCode());
        System.out.println("Details: " + errorPayload.getMessage());
    }
}

3.8 Data Merging Framework (io.milesoft.primitives.merge)

Defines structures used to represent and merge entities, qualifiers, and custom data models across integrations. Highly utilized by scheduling and external sync services.

  • Model: Represents custom dynamic payload data, declaring getKey() and getData().
  • CustomModel: A simple unmodifiable implementation of Model.
  • Qualifier: Defines a key-id mapping (such as linking a local entity to an external provider's ID).
  • MergeData: Immutable aggregator representing user identities, target contact scopes, lists of qualifiers, and associated models.
    • Mutability Support (thaw()): Implements a .thaw() method that returns a fluent Lombok builder pre-populated with current settings, supporting safe modification patterns without mutability risks.
import io.milesoft.primitives.merge.MergeData;
import io.milesoft.primitives.merge.Qualifier;
import io.milesoft.primitives.merge.CustomModel;
import java.util.Map;

// Build complex merge configurations safely
MergeData dataset = MergeData.builder()
    .userId("usr_101")
    .contactId("cnt_202")
    .userQualifier(new Qualifier("google", "oauth_sub_id"))
    .model(new CustomModel("settings", Map.of("theme", "dark")))
    .build();

// Thaw back to a builder to append changes safely
MergeData updated = dataset.thaw()
    .userId("usr_102")
    .build();

4. API Reference & Data Contracts

The tables below document the structural specifications and constraints for the critical model classes within the primitives library.

4.1 Actor

Field Type Description / Constraints
appId String System UUID of the executing application. Required / Not Blank.
accountId String System UUID of the subscriber tenant. Required / Not Blank.
userId String System UUID of the active user. Required / Not Blank.

4.2 Version

Field Type Description / Constraints
major int Major release segment. Must be 0-9999.
minor int Minor feature segment. Must be 0-9999.
patch int Patch bugfix segment. Must be 0-9999.

4.3 ArtifactKey

Field Type Description / Constraints
developerId String Identifier of the package owner or group. Alphanumeric / Not Blank.
artifactId String Identifier of the specific package/library. Alphanumeric / Not Blank.
version Version The target package release. Nullable (indicates "latest" version).

4.4 ApiError

Field Type Description / Constraints
errorCode String Canonical platform error code used for programmatic troubleshooting.
message String Developer-focused description of the failure.
status int Corresponding HTTP Status code (e.g. 400, 401, 404).
timestamp Instant Time instant when the exception occurred.
fieldErrors Map<String, String> Map containing validation failure fields coupled with failure reasons.

4.5 MergeData

Field Type Description / Constraints
userId String System UUID of the user context.
contactId String System UUID of the contact graph identity.
userQualifiers List<Qualifier> List of provider mappings linked to the user. Returns immutable copy.
contactQualifiers List<Qualifier> List of provider mappings linked to the contact. Returns immutable copy.
models List<Model> Merged datasets associated with this execution. Returns immutable copy.

4.6 Qualifier

Field Type Description / Constraints
key String Mapped provider or reference identifier (e.g. quickbooks). Required / Non-null.
id String External identity pointer corresponding to the key. Required / Non-null.