Skip to content

Cross-App Contracts

This page documents the integration contracts between Kubuli apps.

Architecture summary

Ingestion agents (n8n)
  → POST /admin/api/ingest/{type}   (Sanctum service token)
      Admin CMS (Laravel + Filament)
          → Review, approve, promote
              PostgreSQL
                  ← GET /api/v1/...   (JWT or Better Auth session)
                      Web / Mobile clients

Admin → Ingestion agents

Contracts for external callers submitting content to the admin app:

→ See Admin Ingestion for the full endpoint reference.

Auth: Sanctum service token with ingestion:view or ingestion:create ability, plus the matching Spatie permission on the token’s user account.

ServiceBase URL
Localhttps://localhost/admin/api
ProductionTBD

Web / Mobile → API

Contracts for client apps calling the HonoX backend API:

→ See API Overview for the endpoint family reference.

Auth: Bearer JWT from /api/v1/auth/login or /api/v1/auth/guest, or a valid Better Auth session cookie.

ServiceBase URL
Localhttp://localhost:3001
Staginghttps://api.kubuli.platform.mhdevnet.net
ProductionTBD

Response envelope

Most live /api/v1/* data endpoints return a top-level data envelope:

json
{ "data": { ... } }

Known exceptions:

  • GET /api/v1/openapi returns the OpenAPI document directly
  • GET /api/health returns { "status": "healthy", "timestamp": "..." }

List endpoints include pagination metadata:

  • Page-based (GET /api/v1/places): meta.page, meta.limit, meta.total, meta.total_pages
  • Cursor-based (tours, reviews, feed): meta.cursor or meta.next_cursor

Error envelope

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

Shared database

Both the admin app (Laravel) and the API (HonoX) connect to the same PostgreSQL instance. Laravel owns the canonical schema migrations and curated-content write models. @kubuli/database mirrors the live schema for Prisma consumers in the TypeScript apps.

Ownership rule: The admin app is the write surface for curated content. The API is read-only for canonical records (events, places, stories). Media uploads via the API are the exception — community photo submissions go through the API and are moderated in the admin console.

n8n service token lifecycle

  1. Admin creates a source in Ingestion Sources.
  2. Admin selects an n8n workflow template and clicks Provision workflow.
  3. The admin app clones the template in n8n, injects the source-specific service token, and activates the workflow.
  4. The n8n workflow runs on schedule and calls POST /admin/api/ingest/{type} with the source-scoped token.
  5. Deleting the source in the admin console deactivates the n8n workflow and revokes the token.

Built with VitePress