All files / realm/blong-gateway/meta/type schema.ts

100% Statements 99/99
100% Branches 1/1
100% Functions 0/0
100% Lines 99/99

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 1001x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
import {schema} from '@feasibleone/blong';
 
export default schema(async ({lib: {type}}) => ({
    /**
     * Registered OAuth applications (developers' API consumers).
     *
     * The PK is a FK to `core.resource.resourceId`; the clientId is the
     * `core_resource.resourceName`.  `ownerUserId` links the application to the
     * developer's `access.user`.  Client credentials live in
     * `access.credential` (`credentialType: 'clientSecret'`).
     */
    application: type.Object(
        {
            applicationId: type.uuid(),
            ownerUserId: type.uidNull(),
            applicationType: type.stringNotNull(),
            description: type.stringNull(),
            isActive: type.booleanNotNull(),
        },
        {
            constraints: {
                primaryKey: 'applicationId',
                foreign: {
                    applicationId: 'core.resource.resourceId',
                    ownerUserId: 'access.user.userId',
                },
            },
        },
    ),
 
    /**
     * API bundles — metered offerings that wrap an `access.role` (whose
     * capabilities/actions are the bundle's authorized scopes).
     *
     * Modelling the bundle as a role makes authorization uniform in the jwt
     * plugin: an application subscribes with `hasRole` edges and its token's
     * `per` carries the bundle `roleBit`s, resolved by the existing
     * `access.authorization.list`.
     */
    bundle: type.Object(
        {
            bundleId: type.uuid(),
            // Optional in the API (the generic create form does not collect it;
            // `gateway.bundle.add` / `gateway.bundle.merge` always populate it).
            // Still backed by a binary(16) FK to access.role.
            roleId: type.uidNull(),
            isActive: type.booleanNotNull(),
            baseMonthlyCredits: type.bigIntNotNull(),
            rateLimit: type.integerNotNull(),
            rateWindowSec: type.integerNotNull(),
            description: type.stringNull(),
        },
        {
            constraints: {
                primaryKey: 'bundleId',
                unique: {
                    roleId: {},
                },
                foreign: {
                    bundleId: 'core.resource.resourceId',
                    roleId: 'access.role.roleId',
                },
            },
        },
    ),
 
    /**
     * Active subscriptions linking an application to a bundle.
     *
     * `status` is 'active' | 'suspended' | 'cancelled'.  An active subscription
     * also creates the `application hasRole bundleRole` core.triple edge so the
     * application's effective actions (and hence authorization) follow from the
     * bundle.  Cancelling/suspending takes effect immediately at the metering
     * layer (cfg invalidation + active-subscription check).
     */
    subscription: type.Object(
        {
            subscriptionId: type.uuid(),
            applicationId: type.uidNotNull(),
            bundleId: type.uidNotNull(),
            status: type.stringNotNull(),
            startsAt: type.dateTimeNotNull(),
            endsAt: type.dateTimeNull(),
            createdAt: type.dateTimeNull(),
        },
        {
            constraints: {
                primaryKey: 'subscriptionId',
                unique: {
                    appBundle: {columns: ['applicationId', 'bundleId']},
                },
                foreign: {
                    applicationId: 'gateway.application.applicationId',
                    bundleId: 'gateway.bundle.bundleId',
                },
            },
        },
    ),
}));