Addon Application

Overview

Add-on applications are built from classes that inherit the ITfApplicationAddon interface. Tefter.bg scans for these classes during startup and makes them available to users.

Add-on applications also require typed components for their lifecycle. Typically, add-on applications create their own database tables for storing and managing their data.

The standard process for creating and distributing an application for Tefter.bg involves developing a Razor library project and then distributing the result as a NuGet package. For practical examples, you can review the projects of existing providers created by us, such as:

Seed Project GitHub
Talk Application GitHub
Asset Application GitHub

Application project

The usual structure of the projects is as follows:

Data provider project

Application class

This is they usual structure of the method and its properties and callback methods.

namespace WebVella.Tefter.Seeds.SampleApplication;

public class SampleApp : ITfApplicationAddon
{
	public const string ID = "1492d19b-c8b2-4abb-9e88-2b645ba518ff";
	public const string NAME = "Sample Application";
	public const string DESCRIPTION = "Sample Application Description";
	public const string FLUENT_ICON_NAME = "Album";

	public Guid Id { get; init;} =  new Guid(ID);
	public string Name { get; init;} =  NAME;
	public string Description { get; init;} =  DESCRIPTION;
	public string FluentIconName { get; init;} =  FLUENT_ICON_NAME;

	public void OnStart()
	{
	}

	public void OnRegisterDependencyInjections(IServiceCollection services)
	{
		services.AddSingleton<ISampleAppService, SampleAppService>();
	}
}

Data Migrations

Since add-on applications can have their own data tables, migrations are used to create and manage these tables across different versions.

A typical migration class must inherit the ITfApplicationMigration interface and have the TfApplicationMigration class attribute.

These classes are discovered and executed during the program's startup phase, in ascending order based on the version string defined in the attribute.

Here's an example of such a migration:

using Microsoft.Extensions.DependencyInjection;
namespace WebVella.Tefter.Seeds.SampleApplication.Migrations;

[TfApplicationMigration(SampleApp.ID, "2025.04.04.01")]
public class SampleAppMigration2025040401 : ITfApplicationMigration
{
	public Task MigrateDataAsync(ITfApplicationAddon app, IServiceProvider serviceProvider, ITfDatabaseService dbService)
	{
		ISampleAppService sampleAppService = serviceProvider.GetService<ISampleAppService>();

		sampleAppService.AddNote("Test note 1");
		sampleAppService.AddNote("Test note 2");
		sampleAppService.AddNote("Test note 3");

		return Task.CompletedTask;
	}

	public Task MigrateStructureAsync(ITfApplicationAddon app, TfDatabaseBuilder dbBuilder)
	{
		dbBuilder
			.NewTableBuilder(Guid.NewGuid(), "sample_app_notes")
			.WithColumns(columns =>
			{
				columns
					.AddGuidColumn("id", c => { c.WithAutoDefaultValue().NotNullable(); })
					.AddShortTextColumn("note_text", c => { c.NotNullable().WithDefaultValue(""); })
					.AddDateTimeColumn("created_on", c => { c.WithDefaultValue(DateTime.UtcNow); });
			})
			.WithConstraints(constraints =>
			{
				constraints
					.AddPrimaryKeyConstraint("pk_sample_app_note_id", c => { c.WithColumns("id"); });
			});


		return Task.CompletedTask;
	}
}

PageComponent Components

This component enables an application to be integrated into space pages, allowing the application to have its own page type within the Space navigation. It must inherit the ITfSpacePageAddon interface. Read more.

Admin or Dashboard Page

This component allows an application to inject its own administrative or general dashboard page. For an admin panel page, it should inherit the ITfScreenRegionComponent<TfAdminPageComponentContext> interface, and for a public dashboard page, the interface is ITfScreenRegionComponent<TfPageComponentContext>. Read more.

View Column Type

If you need a specific data selection in the space view, this is the way to go. Read more

View Column Components

If you need a specific data presentation in the space view, this is the way to go. Read more