Skip to content

Mantle2 (Drupal/PHP backend)

Mantle2 is the authoritative REST API for The Earth App. It persists users, activities, events, prompts, and articles and exposes a live OpenAPI 3.1 schema.

Core traits:

  • Drupal 11.2+ with PHP 8.4+ and Symfony 7.3+ routing/controllers
  • OpenAPI auto-generation from route metadata
  • Security: BasicAuth (admin/ops) + Bearer JWT (end users)
  • Performance: Redis caching, rate limiting, pagination helpers
  • Integration: Bridges to Cloud service for AI-enriched content

Flow overview

  • Client -> Mantle2 -> Controllers -> Services/DB -> Response
  • Cloud -> Mantle2 (POST articles/prompts) for persistent storage

Request lifecycle

  1. Auth validated (Basic or Bearer)
  2. CORS/rate limits applied
  3. Controller reads inputs (query/path/body)
  4. Service/query + optional Redis cache
  5. JSON response with consistent schemas

OpenAPI docs

  • Schema endpoint: /openapi (JSON)
  • Swagger UI: /docs (if enabled)

ID Format Standard

All entity IDs in Mantle2 follow a 24-digit zero-padded format:

"000000000000001234567890"

This format ensures:

  • Consistent ID length across all entities
  • Easy visual identification and debugging
  • Compatibility with frontend and cloud services
  • Database-agnostic ID representation

Implementation

IDs are formatted using GeneralHelper::formatId($id):

php
str_pad($id, 24, '0', STR_PAD_LEFT)

Examples

  • User ID: "000000000000000123456789"
  • Activity ID: "000000000000001234567890"
  • Article ID: "000000000000002345678901"
  • Event ID: "000000000000003456789012"
  • Prompt ID: "000000000000004567890123"
  • Notification ID: "000000000000006789012345"

Date/Time Format

All timestamps use ISO 8601 format:

"2025-01-10T16:00:00Z"

Internally stored as Unix timestamps (milliseconds for events), formatted via GeneralHelper::dateToIso($timestamp).

Pagination

Standard pagination structure across all list endpoints:

json
{
	"items": [...],
	"page": 1,
	"limit": 20,
	"total": 42
}
  • Default limit: 20
  • Maximum limit: 250
  • Page index starts at 1

Status codes

  • 200 OK, 201 Created, 204 No Content
  • 400 Bad Request, 401 Unauthorized, 403 Forbidden
  • 404 Not Found, 409 Conflict, 429 Too Many Requests

Common parameters

  • Pagination: limit, page
  • Search: search
  • Sort: sort=asc|desc|rand

Common error shape

json
{
	"error": {
		"code": "E404",
		"message": "Resource not found",
		"details": {}
	}
}

Entity Types and Enums

ActivityType (29 values)

HOBBY, SPORT, WORK, STUDY, TRAVEL, SOCIAL, RELAXATION, HEALTH, PROJECT, PERSONAL_GOAL, COMMUNITY_SERVICE, CREATIVE, FAMILY, HOLIDAY, ENTERTAINMENT, LEARNING, NATURE, TECHNOLOGY, ART, SPIRITUALITY, FINANCE, HOME_IMPROVEMENT, PETS, FASHION, OTHER

EventType (3 values)

  • IN_PERSON — Physical event at a location
  • ONLINE — Virtual event
  • HYBRID — Both in-person and online options

Visibility (3 values)

  • PUBLIC — Visible to all users
  • UNLISTED — Requires login, not in public listings
  • PRIVATE — Only visible to owner, admins, attendees, mutual friends

Privacy (4 values)

  • PUBLIC — Visible to everyone
  • MUTUAL — Visible to mutual friends
  • CIRCLE — Visible to friend circle
  • PRIVATE — Visible only to user

Cross-service relationship

  • Cloud enriches and curates content, then POSTs to Mantle2
  • Crust (Nuxt) reads from Mantle2 for user-facing pages
  • Ocean algorithms run in Cloud; Mantle2 remains the source of truth

Key Entities

Users

Full user profile management with authentication, privacy settings, and relationships. See users.md for complete documentation.

Example user ID: "000000000000000123456789"

Activities

Global catalog of activities users can add to their profiles. Up to 5 ActivityType tags per activity. See activities.md for complete documentation.

Example activity ID: "000000000000001234567890"

Articles

Scientific publications with user commentary and rich Ocean metadata (source, abstract, keywords, etc.). See articles.md for complete documentation.

Example article ID: "000000000000002345678901"

Events

User-organized gatherings with location, type, visibility, and attendee management. See events.md for complete documentation.

Example event ID: "000000000000003456789012"

Prompts

Daily reflection questions with user responses. PUBLIC prompts auto-expire after 2 days. See prompts.md for complete documentation.

Example prompt ID: "000000000000004567890123"

Notifications

User-scoped notifications for system events, articles, friend requests, etc. See notifications.md for complete documentation.

Example notification ID: "000000000000006789012345"

Performance & Caching

  • Redis caching for frequently accessed data
  • Rate limiting to prevent abuse
  • Database query optimization with indexes
  • Pagination to limit response sizes
  • Connection pooling for database access

Security

Authentication Methods

  1. Basic Auth — Admin/ops access using username:password
  2. Bearer JWT — End-user authentication with JSON Web Tokens

Authorization

  • Role-based access control (RBAC)
  • Resource ownership validation
  • Privacy setting enforcement
  • Admin-only endpoints clearly marked

Data Protection

  • Password hashing (bcrypt/argon2)
  • CORS configuration
  • Rate limiting
  • Input validation and sanitization
  • SQL injection prevention (parameterized queries)