Skip to content

Nafinity

Nafinity is a Kanban application built on NAF. Its host skeleton configures the application; the published naf/board dependency supplies product behavior. Extensions use registries, providers and events while the host controls deployment and local overrides.

Host and package layout

The repository you clone is a skeleton. The product is a dependency.

naf/nafinity     the installation you own
  └── naf/board  everything the application does
        └── naf/framework and the required NAF plugins

Keep host configuration and extensions in the skeleton. Product code belongs to naf/board; avoid editing installed vendor files so package updates preserve local changes.

app/
  composer.json      what your installation requires
  bootstrap.php      nine lines: autoload, BASE_PATH, run
  .env               the application's own environment
  src/
    config.php       everything the application runs on, in one file
    routes.php       routes you add; a path here wins over the board's
    extensions.php   your last word on what the application offers
    Controllers/     your code, namespace Nafinity\
    views/           a template here wins over the board's
  public/index.php   the entry point; assets are published in beside it
  storage/           uploads, sessions, queue and scheduler state
docker/, Makefile    how it runs locally, and the image it ships as

The skeleton contains the entry points and configuration needed to run the installed product.

Local setup

Nafinity ships with Docker Compose and a Makefile. One command builds the image, installs dependencies, migrates, writes the declared roles, publishes assets, seeds a demo project and starts everything:

make first-install

It is then at https://localhost, with a locally trusted certificate the same command issued. make help lists the rest; the ones you will want early are make assets after updating a package, make migrate, and make logs.

Package stylesheets and scripts are published into app/public/. After adding or updating a package, run make assets. Otherwise registered assets may return 404. make health compares registered assets with published files and reports missing ones.

Nafinity runs on MariaDB or MySQL; Compose brings MariaDB along. MySQL 8.x installations need naf/board 0.1.5 or newer, including its naf/rbac 0.1.3 minimum, so role migrations and writes quote the reserved system column.

Back up the database and private storage before upgrading. For the workflows below, use naf/board 0.1.6 or newer. After updating, apply migrations, synchronize roles, publish assets, restart long-running services and run make health. The new time journal starts with the migration; historical ticket totals are not backfilled.

composer install takes naf/board and the plugins from Packagist at the versions recorded in the committed lock. When to update them is your decision: make composer-update, then make migrate, make roles and make assets.

Container deployment

Use the public ghcr.io/nafphp/nafinity image with compose.production.yaml. It contains published packages from the committed Composer lock and published assets. The stack supplies TLS, persistent database/storage volumes and explicit deployment commands. Follow Deploying Nafinity containers for first-account setup, updates, backups and restoration.

Application commands

make wraps the ones a development installation needs daily; these are what it wraps, and what a deployment runs directly. From the repository root, bin/naf command:list selects local PHP inside the container or the Compose app service on the host. From app/, use bin/naf command:list as well. Docker failures remain errors rather than falling back to another runtime. Set NAF_CLI_RUNTIME=local or NAF_CLI_RUNTIME=compose to choose explicitly; NAF_CLI_SERVICE selects another Compose service.

Command What it does
nafinity:seed Demo data, and only into a database that has none
nafinity:assets:publish Copy every package's stylesheets and scripts into app/public/
nafinity:assets:check Report registered assets missing from the public directory
nafinity:assets:remove Remove previously published files using the publication record, including after a package was removed
nafinity:user Create an account, reading its password from standard input
nafinity:admin Grant the admin role to an existing account, while nobody holds it yet
nafinity:grant-default Give accounts holding no role at all the one an ordinary account has
nafinity:migrations:rename Rewrite the namespace recorded for applied migrations, after renaming your own

The first four are what make assets, make seed and make health call. The rest are for the moments an installation is being set up or repaired, which is why they are commands rather than screens. make health checks pending migrations and the configured attachment storage as well as database readiness.

Account appearance and language

Personal settings choose a built-in or published custom theme separately from light, dark or system brightness. These choices persist across projects and sign-in. Existing accounts retain their explicit palette; new preferences can follow the installation default. The brightness button retains the selected theme. Administrators can publish custom themes; see appearance and configuration.

German is the base language. English covers core navigation, ticket fragments, validation, activity vocabulary, AI tool titles and browser messages. Project names, ticket text and extension-provided wording remain their authors' content. Local AI selection uses only the authorized catalog, keeps required read tools with actions, and falls back to bounded German/English keyword selection when embeddings are unavailable. Writes still require confirmation.

Exporting boards

Board settings export that board's tickets. Installation settings can export one board or all active boards the current account may export. CSV, JSON and installed exporter formats use the same selection; status, archive state and inclusive UTC update dates can narrow the result. Each board's export and field permissions are checked separately, including in a combined download. Managing installation settings does not grant access to another board.

Daily workflows

  • Working with tickets: workspace search, saved/shareable filters, My tickets, relevant notifications, keyboard access, personal sidebar and relationships.
  • Accounts and invitations: invite people, edit authorized accounts, manage global roles and recover local passwords.
  • Hours and invoice drafts: personal time reports, invoice positions and durable draft handovers.
  • Appearance and configuration: shared branding, themes, email design and sourced installation overrides.
  • Mail replies: append authorized replies from an existing mailbox to existing tickets.

Host customization

Your own code goes in app/src/ under the Nafinity\ namespace. The namespace is yours: nothing in naf/board refers to it, so rename it in composer.json if you would rather call it something else.

Overriding a template. Copy the one you want from vendor/naf/board/src/views/ into app/src/views/, keeping the path. Host views win over the package's.

Changing what the application offers. app/src/extensions.php runs after Board's providers, so anything reachable there can be replaced or removed — including a definition an extension just added:

use function Naf\Board\extensions;

extensions()->boardFilters()->remove('example.only-mine');

Adding a plugin. composer require it. A package of type naf-plugin is found through Composer's installed-packages metadata. Plugins declare boot prerequisites in their own manifests, so a normal Nafinity installation has no plugins.php. An extension that registers a Board provider requires naf/board and declares extra.naf.boot.before: ["naf/board"]; Board runs the provider after its own defaults. Use bin/naf plugins:debug to inspect the order.

For the mechanisms a plugin has once it is installed, see how Nafinity is extended.

Package responsibilities

These packages provide the main application capabilities:

It needs For
naf/view Templates, with host paths winning over package paths
naf/database, naf/orm Schema migrations, repositories
naf/auth, naf/session Signing in against its own user model
naf/form Validation and CSRF
naf/queue, naf/schedule Notification mail, reminders
naf/storage Ticket attachments
naf/i18n German source strings, English translation
naf/cli nafinity:seed, nafinity:assets:publish and friends
naf/rate-limit Slowing down sign-in attempts
naf/mcp Exposing tools to a local model
naf/rbac Roles and permissions an installation can edit
naf/websocket Live updates, and who else is on a board

Extension reference

The extension reference — every registry, every contract, what a plugin may declare and what happens when it is removed — ships with the board itself, in docs/Extensibility.md of naf/board. It is exhaustive and versioned with the code it describes, which a page here could not be.

Use that versioned reference when implementing an extension.