ma496
@ma496
Public Skills
notifications
by ma496
Raise an in-app notification from the API and make it render in the web app — INotificationService, user / tenant-wide / platform-wide addressing and the tenant scope each needs, the translation-key contract for title/message, groups and metadata, the SignalR hub each committed notification is pushed through (its groups, publishing after commit, NewUserNotificationsAsync), and the badge. Use when a feature needs to tell users something happened.
permissions
by ma496
Add, rename or remove a permission end-to-end across the API and the web app (Allow.cs, the feature's IPermissionDefinitionProvider, the endpoint, allow.ts, auth-urls.ts, nav-items), including gating one on the tenant's plan with RequireFeatures. Use whenever authorization for a screen or endpoint changes.
frontend-page
by ma496
Add a route to the Next.js app under src/frontend/web/app/[lang] — server page component, _components client component, locale-prefixed routing, the three access layers (proxy.ts sign-in check, auth-urls.ts permissions, tenant-scope routing), i18n keys, nav-items and searchable-items registration. Use for any new screen that is not a full CRUD set.
frontend-tests
by ma496
Write and run Vitest tests for the web app in src/frontend/web — colocated *.test.ts files, what is worth testing (pure helpers, route and tenant-scope rules, reducers, middleware, source-reading rules such as "nothing calls /tenants/switch", client/API mirrors, locale files) and how to structure cases. Use when changing frontend logic that has rules worth pinning down.
frontend-crud
by ma496
Build the standard list/create/update/delete screens for an entity in src/frontend/web — data table with URL-synced paging, sorting, search, filter panel and export, icon-only toolbar actions and a per-row actions menu gated by permission, row state and plan limits, plus Formik + Yup create/update forms. Use when scaffolding CRUD UI for a new entity.
settings
by ma496
Add or change a setting — a typed value the platform and each tenant may override (the setting class, its validator, the slice's SettingsProvider, a default from code or from configuration with FromConfiguration, [SecretSetting] properties), read it with ISettingProvider inside a request or with GetAsync<T>(tenantId) outside one, the /settings endpoints and the admin screen, and the Settings test collection. Use when behaviour should be configurable per tenant at run time rather than fixed in code or appsettings.
new-project
by ma496
Scaffold a new application from this template with the dotnet efn CLI (efn cp -n <name>), and do the post-create setup — database password, git repository, initial migration, running the API and the web app, and signing in with the seeded accounts. Use when asked to create/start a new project, or when a freshly generated project does not build or run yet.
coding-conventions
by ma496
Naming, file layout, and code-style rules for this codebase (C# API and Next.js web). Use before writing or reviewing any C# or TypeScript file so new code matches the surrounding style — namespaces, XML docs, sealed/primary constructors, kebab-case web files, i18n key shapes.
template-maintenance
by ma496
Work on the EasyForNet template repository itself — how src/ and the agentic layer ship to generated projects, the dotnet efn CLI in tool/, the copy and rewrite rules, locale filtering, the version/tag coupling, testing the generator locally, and the publish flow. Use when changing the generator, adding root-level files or anything under .claude, or releasing a new version.
multi-tenancy
by ma496
Work with tenant isolation — tenant-owned entities (IHaveTenant/IMayHaveTenant) and the AppDbContext filter and stamping, ITenantContext and its scopes, tenant vs platform scope, User.IsPlatform, memberships and seats, switching tenants, background work outside a request, and isolation tests. Use when adding data that belongs to a tenant, reading or changing the active tenant, writing code that runs without a request, or reviewing anything that could leak rows across tenants.
ui-component
by ma496
Build or extend a shared React component in src/frontend/web/components — which folder it belongs in, the cva variant + cn pattern, forwardRef, Formik-aware form fields, icon-only controls with tooltips, portaled menus, barrel exports, and the dark-mode/RTL class rules. Use when adding a reusable component, a new form field, or a variant to an existing one.
localization
by ma496
Work with i18n across the API and the web app — adding translation keys to the backend resource files, the three translator entry points (client hook, server helper, non-component) imported from @/i18n, the flat dictionary the API serves, tenant and platform overrides and the admin screen, the tests that keep every locale in step, adding or removing a language, RTL handling, and how locale-prefixed routing works. Use when adding user-facing text or a new language.
background-jobs
by ma496
Run work off the request thread with Hangfire — fire-and-forget enqueues, recurring jobs registered in Program.cs, establishing the tenant scope a job acts in, the email-sending pattern, the platform-only dashboard, and what runs under Testing. Use when a request should not wait for slow work (email, cleanup, external calls) or when adding a scheduled task.
rtk-query-api
by ma496
Add or change an RTK Query API slice and its DTOs under src/frontend/web/store/api — injectEndpoints on the shared appApi, DTO files mirroring the backend (including the tenant and system-created markers), feature barrels, and the rules for cache tags (providesTags/invalidatesTags, tags shared across slices, and why changing tenant is a new address rather than a cache reset).
redux-state
by ma496
Add or change client state in src/frontend/web/store — Redux Toolkit slices, store registration, typed useAppSelector/useAppDispatch hooks, the auth/tenant session state, and middleware. Use when you need state that is not server data, and to decide between a slice and the RTK Query cache.
backend-tests
by ma496
Write or run xUnit v3 integration tests for the API under src/backend/Tests — App/AppTestsBase fixtures, typed FastEndpoints client calls, Bogus fakers, FluentAssertions, the shared seeder and tenants, tenant-aware base classes, and the parallel-safety rules. Use whenever an endpoint or backend service is added or changed.
backend-entity
by ma496
Add or change an EF Core entity — base classes, audit/soft-delete/normalized-property/system-created interfaces, the tenant markers (IMayHaveTenant/IHaveTenant) and the tenant-scoping architecture test, IEntityTypeConfiguration, the AppDbContext DbSet, and the migration commands. Use whenever a database table or column changes.
backend-feature
by ma496
Create a new vertical-slice feature under src/backend/Source/Features (Core + Endpoints + Feature.cs + permission and entitlement providers), or work across existing features. Use when adding a whole capability rather than a single endpoint, and whenever cross-feature dependency, [AllowOutside] or [NoDirectUse] questions come up.
backend-endpoint
by ma496
Add or change a FastEndpoints endpoint in src/backend/Source/Features. Use when the task is "add an API endpoint", "expose X over HTTP", or when editing an existing *Endpoint.cs — covers the one-file layout (endpoint + request + validator + response + Mapperly mapper), route groups, permissions, tenant scope and plan checks inside a handler, system-created guards, list/paging, and error codes.
api-error-handling
by ma496
Report an API failure end-to-end — ThrowError with an ErrorCodes constant, plan refusals (FeatureDisabledException / FeatureLimitExceededException), the ProblemDetails shapes the API emits, how the API localizes a coded error before it ever reaches the browser, and the web side (getApiErrorMessages, getErrorCode, ApiErrorMessages, apiErrorAlert). Use when adding a new failure case or when an error surfaces wrong or untranslated in the UI.
commit
by ma496
Commit the current changes — pick the scope, stage only what belongs to it, write the message in this repository's style, and commit as the user git is configured with, with no co-author or attribution trailer. Use whenever a change is committed, by hand or at the end of /feature, /fix, /ship or /auto.
file-storage
by ma496
Upload, serve and delete files — the FileManagement feature (IFileService/IStorageProvider), tenant vs account-owned attribution on StoredFile, payload size limits and the plan's FileManagement features, storing a file reference on an entity, and the FileUpload/MultiFileUpload/ImagePreview components on the web side. Use when a feature needs attachments, avatars or any binary content.
feature-management
by ma496
Add or change a feature (entitlement) end-to-end — FeatureNames.cs, the slice's FeaturesProvider, feature-names.ts, and gating a permission with RequireFeatures or checking one with IFeatureChecker. Use when a capability should depend on the tenant's plan rather than on the caller's role.