Table of Contents

Interface IGuildRankService

Namespace
FishMMO.Database.Npgsql.Services.Interfaces
Assembly
FishMMO-DB.dll

Service interface for a guild's editable rank ladder.

public interface IGuildRankService

Remarks

The rank rows are the authority for what a member may do. Nothing in this interface takes a requester: authorisation is the server's job and it happens before these calls, against the rows FetchManyAsync(long, CancellationToken) returns. A storage service that also decided permissions would be two responsibilities with one test surface.

Methods

CreateAsync(GuildRankData, int, CancellationToken)

Inserts a new rank row.

Task<DatabaseResult> CreateAsync(GuildRankData rank, int maxRanks, CancellationToken cancellationToken = default)

Parameters

rank GuildRankData

The rank to insert.

maxRanks int

Maximum rank rows one guild may own.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

A result indicating success or failure.

DeleteAsync(long, byte, CancellationToken)

Deletes a rank row, refusing while any member still holds it.

Task<DatabaseResult> DeleteAsync(long guildId, byte rankOrder, CancellationToken cancellationToken = default)

Parameters

guildId long

Guild ID.

rankOrder byte

The rank position to delete.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

A result indicating success or failure.

Remarks

The occupancy test and the delete are ONE statement. Split across two round trips, a member could be moved into the rank between them and end up holding a rank that no longer exists — which reads back as no permissions at all, quietly, forever.

EnsureDefaultsAsync(long, IReadOnlyList<GuildRankData>, CancellationToken)

Creates the default rank ladder for a guild if it does not already have one.

Task<DatabaseResult<int>> EnsureDefaultsAsync(long guildId, IReadOnlyList<GuildRankData> defaults, CancellationToken cancellationToken = default)

Parameters

guildId long

Guild ID.

defaults IReadOnlyList<GuildRankData>

The rows to seed, in any order.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<int>>

The number of rows actually inserted.

Remarks

IDEMPOTENT. Every row is inserted with ON CONFLICT (guild_id, rank_order) DO NOTHING, so running this against a guild that already has ranks changes nothing and returns zero. That is what makes it safe to call on every guild read, which is in turn what makes the migration of existing guilds require no migration step at all: a guild created before rank rows existed grows them the first time anybody looks at it, with the permissions its old enum ranks implied.

FetchManyAsync(long, CancellationToken)

Fetches every rank row for a guild, ordered by rank order ascending.

Task<DatabaseResult<IReadOnlyList<GuildRankData>>> FetchManyAsync(long guildId, CancellationToken cancellationToken = default)

Parameters

guildId long

Guild ID.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<IReadOnlyList<GuildRankData>>>

The guild's rank ladder.

UpdateAsync(long, byte, string, long, long, CancellationToken)

Updates one rank's name and permission mask.

Task<DatabaseResult> UpdateAsync(long guildId, byte rankOrder, string name, long permissions, long incomingVersion, CancellationToken cancellationToken = default)

Parameters

guildId long

Guild ID.

rankOrder byte

The rank position to update.

name string

New display name.

permissions long

New permission bit mask.

incomingVersion long

The authoritative, monotonic version for this update.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

A result indicating success or failure.