Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/strange-singers-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@wbce-d9/types': minor
'@wbce-d9/api': minor
'@wbce-d9/app': minor
'tests-blackbox': patch
---

Add a way to define check constraints through api and web app
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable('directus_collections', (table) => {
table.json('check_filter').nullable();
});
}

export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable('directus_collections', (table) => {
table.dropColumn('check_filter');
});
}
22 changes: 22 additions & 0 deletions api/src/database/system-data/fields/collections.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,25 @@ fields:

- field: collapse
hidden: true

- field: check_filter_divider
special:
- alias
- no-data
interface: presentation-divider
options:
icon: rule
title: $t:field_options.directus_collections.check_filter_divider
width: full

- field: check_filter
special:
- cast-json
interface: system-filter
options:
collectionField: collection
collectionRequired: true
allowFieldComparison: true
includeRelations: false
relationalFieldSelectable: false
width: full
26 changes: 21 additions & 5 deletions api/src/services/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { clearSystemCache, getCache } from '../cache.js';
import { ALIAS_TYPES } from '../constants.js';
import type { Helpers } from '../database/helpers/index.js';
import { getHelpers } from '../database/helpers/index.js';
import getDatabase, { getSchemaInspector } from '../database/index.js';
import getDatabase, { getDatabaseClient, getSchemaInspector } from '../database/index.js';
import { systemCollectionRows } from '../database/system-data/collections/index.js';
import emitter from '../emitter.js';
import env from '../env.js';
Expand All @@ -24,6 +24,8 @@ import type {
MutationOptions,
} from '../types/index.js';
import { getSchema } from '../utils/get-schema.js';
import { applyCollectionCheckConstraint } from '../utils/check-constraints.js';
import logger from '../logger.js';

export type RawCollection = {
collection: string;
Expand Down Expand Up @@ -389,10 +391,24 @@ export class CollectionsService {
.first());

if (exists) {
await collectionItemsService.updateOne(collectionKey, payload.meta, {
...opts,
bypassEmitAction: (params) =>
opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
await collectionItemsService.knex.transaction(async (tsx) => {
collectionItemsService.knex = tsx;

if (payload.meta?.check_filter !== undefined) {
const client = getDatabaseClient();

if (client === 'postgres') {
await applyCollectionCheckConstraint(tsx, collectionKey, payload.meta?.check_filter, this.schema);
} else {
logger.warn(`Check constraints are only enforced for postgres database.`);
}
}

await collectionItemsService.updateOne(collectionKey, payload.meta as CollectionMeta, {
...opts,
bypassEmitAction: (params) =>
opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
});
});
} else {
await collectionItemsService.createOne(
Expand Down
1 change: 1 addition & 0 deletions api/src/types/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type CollectionMeta = {
item_duplication_fields: string[] | null;
accountability: 'all' | 'accountability' | null;
group: string | null;
check_filter?: Record<string, any> | null;
};

export type Collection = {
Expand Down
Loading
Loading