> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fapost.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> What FaPost Core is, and who each part of this documentation is for.

**FaPost Core is a platform for building conversational assistants.** An assistant
connects to messaging channels such as Telegram and WhatsApp, holds conversations
with contacts, and runs them through flows designed on a visual canvas — with
contacts, segments, broadcasts, and conversation history around it.

This repository is Core: the platform without the SaaS shell and without vertical
product packages.

<Accordion title="What is a flow?">
  A flow is a directed graph, stored as JSON, that describes a conversation. Each
  node does one thing — send a message, wait for a reply, branch on a condition,
  call an HTTP endpoint, query a knowledge base — and edges connect a node's
  outcomes to whatever comes next.

  At runtime an engine walks that graph for one contact, resolving each node's
  handler by the pair `(type, version)` and keeping the conversation's state
  between steps. A node handler never decides which node runs next: it reports
  which outcome occurred, and the graph decides where that leads.

  That separation is what makes a flow editable by someone who does not write
  code, and a node reusable in flows its author never saw.
</Accordion>

## What you can build

Most installations start as a bot that answers questions on one channel. The
platform is not limited to that: an assistant can qualify leads, run a
multi-step intake form, notify a team, look up records in another system through
an HTTP call, or broadcast to a segment of contacts on a schedule.

Because everything is multi-tenant from the ground up, one installation can serve
many independent organisations, each with its own assistants, contacts, and data —
without a line of `if (isSaas())` anywhere in the runtime.

## Packages

FaPost is split into three Composer packages plus a standalone Go service. The
split is not organisational tidiness — it is what makes the platform extensible
without freezing its internals.

<CardGroup cols={2}>
  <Card title="fapost/core" icon="cube">
    The platform itself: domains, flow engine, admin panels, and the Vue builder.
    This is the application you deploy.
  </Card>

  <Card title="fapost/foundation" icon="handshake">
    The public contract layer for Solutions, Plugins, and external integrations.
    Everything an extension is allowed to depend on.
  </Card>

  <Card title="fapost/support" icon="screwdriver-wrench">
    Reusable primitives: the ULID trait, a base model, model concerns, and the
    builder schema field classes.
  </Card>

  <Card title="gateway" icon="bolt">
    An optional Go service that accepts, verifies, and queues provider webhooks
    without involving PHP.
  </Card>
</CardGroup>

### fapost/core

The application: thirteen domains under `app/Domains`, the flow engine, the
Filament admin and assistant panels, and the Inertia + Vue flow builder. It
depends on both packages below and is what an operator installs.

Core is where a **Feature** lives — a capability that belongs to the product
surface and releases with the platform. Anything narrower belongs outside it.

### fapost/foundation

The contract layer. Node handlers, data accessors, channel and messaging
interfaces, RAG adapters, the plugin and solution lifecycle base classes, and the
DTOs that travel between them.

This package is the extension boundary. A Solution or Plugin depends on
`fapost/foundation` and never on `App\…`, which is what lets Core refactor its
own internals without breaking anything built on top. See
[Stability policy](/extending/stability-policy).

It has no FaPost dependencies of its own — only PHP 8.4, `illuminate/support`,
`psr/http-message`, and `spatie/laravel-data`.

### fapost/support

Primitives with no domain meaning. `HasUlidPrimaryKey`, a `BaseModel`, concerns
for computed attributes and utilities — and the field classes that describe a
node's configuration form: `TextField`, `SelectField`, `StatePickerField`,
`ObjectArrayField` and the rest, assembled into a `Schema` of `Section`s.

`fapost/support` depends on `fapost/foundation`. The arrow runs one way and never
back toward Core.

<Note>
  Both packages live in their own repositories under
  [fapost-lab](https://github.com/fapost-lab). During development they are checked
  out into `packages/` and symlinked into `vendor/`; in production they resolve
  from git like any other dependency. See
  [Development setup](/extending/development-setup).
</Note>

### gateway

A Go service in `gateway/`, shipped inside the Core repository rather than as a
Composer package, because it is not PHP.

It sits in front of webhook ingress: rate-limits by channel, resolves the routing
entry from Redis, verifies the provider's signature, claims an idempotency key,
and pushes the job — about a millisecond, with no PHP process involved. It knows
nothing about any particular platform; each channel adapter publishes a
declarative **ingress spec** describing how its webhook is signed, and both the Go
and PHP implementations are held to the same golden file so they cannot drift.

It is optional. Without it, webhooks go to the Laravel route exactly as they
always have. See [Webhook gateway](/self-hosting/gateway).

## Licence

Core and both packages are **Apache-2.0**.

Apache-2.0 is permissive — a Solution or Plugin you build on FaPost can be
licensed however you like, including commercially, and you are not obliged to
publish it. What it adds over MIT is an explicit patent grant: every contributor
licenses the patents covering their contribution to everyone who uses the
software, and that grant terminates for anyone who brings a patent suit over it.
For a platform meant to be built on by third parties, that predictability is worth
more than the shorter licence text.

## Where to go

<CardGroup cols={2}>
  <Card title="Using FaPost" href="/using/concepts" icon="wand-magic-sparkles">
    Build an assistant, design flows, manage contacts and broadcasts.
  </Card>

  <Card title="Self-Hosting" href="/self-hosting/overview" icon="server">
    Install, run, and upgrade FaPost on your own infrastructure.
  </Card>

  <Card title="Extending" href="/extending/extension-model" icon="puzzle-piece">
    Build a Solution or Plugin on the public contracts.
  </Card>

  <Card title="Contributing" href="/contributing/local-setup" icon="code-branch">
    Work on Core itself.
  </Card>
</CardGroup>

[Reference](/reference/foundation-contracts) holds the contracts, schemas, queues,
and commands the other sections point at.

## Extending and Contributing are separate on purpose

The two developer sections describe the same system from opposite sides of a
boundary, and the boundary is the point.

**Extending** documents the public surface: the contracts in `fapost/foundation`
that Core undertakes not to break. Everything there is a promise.

**Contributing** documents Core's internals: its domains, its runtime, the
decisions that shape it. Nothing there is a promise — it is refactored freely.

An extension built against Contributing's material will break. That is not a
failure of documentation; it is the arrangement that lets Core keep improving
without coordinating with every extension ever written.

## The shape of the runtime

A message arrives on a webhook, is verified and acknowledged in milliseconds, and
is handed to a queue. A worker establishes the tenant context, guards against
duplicates and races, and hands the message to the flow engine. The engine walks
the graph until the flow finishes or pauses for a reply.

Three properties are worth knowing up front, because most of the platform's rules
follow from them:

**Tenant context is mandatory.** There is no default tenant and no single-tenant
mode. Code that needs context and lacks it fails immediately rather than reading
someone else's data.

**Flows are versioned documents.** A running session holds the flow definition it
started with. Publishing a change affects the next conversation, not the one in
progress.

**Queues are separated by purpose.** A broadcast to fifty thousand contacts must
not delay the reply to the person who just asked a question.

## Status

The platform is pre-1.0. The Solution and Plugin lifecycles exist as contracts but
their tooling is still being built; where something is not finished, these pages
say so rather than describing an intention as a fact.
