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.