Fixed issues with query builder

This commit is contained in:
Umar Adilov 2026-06-01 23:18:12 +05:00
parent a1c95a019a
commit f04aaca29e
6 changed files with 899 additions and 632 deletions

View File

@ -5,7 +5,7 @@ const nextConfig: NextConfig = {
remotePatterns: [ remotePatterns: [
{ {
protocol: 'https', protocol: 'https',
hostname: 'media.bambooapp.ai', hostname: 'media.taylordb.ai',
pathname: '/files/**', pathname: '/files/**',
}, },
{ {

View File

@ -7,7 +7,8 @@
"dev": "next dev --turbopack", "dev": "next dev --turbopack",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "eslint ." "lint": "eslint .",
"regenerate:types": "npx @taylordb/cli generate-schema af483cef-ec47-48fc-b186-e11022dbb0e2 src/shared/database.types.ts"
}, },
"dependencies": { "dependencies": {
"@hookform/resolvers": "^5.0.1", "@hookform/resolvers": "^5.0.1",
@ -25,7 +26,8 @@
"@radix-ui/react-toast": "^1.2.11", "@radix-ui/react-toast": "^1.2.11",
"@radix-ui/react-tooltip": "^1.2.6", "@radix-ui/react-tooltip": "^1.2.6",
"@reduxjs/toolkit": "^2.7.0", "@reduxjs/toolkit": "^2.7.0",
"@taylordb/query-builder": "^0.10.1", "@taylordb/cli": "^0.18.2",
"@taylordb/query-builder": "^0.18.2",
"aos": "^2.3.4", "aos": "^2.3.4",
"axios": "^1.9.0", "axios": "^1.9.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",

639
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,33 @@
import { isEmpty } from 'lodash'; import { TaylorDatabase } from '@/shared/types/database.types';
import { type TaylorColumnRaw<TColumn> = TColumn extends {
AttachmentColumnValue, raw: infer TRaw;
TableRaws, isRequired: true;
} from '@/shared/types/database.types'; }
? TRaw
: TColumn extends { raw: infer TRaw }
? TRaw | undefined
: never;
// Helper to get image URL from Attachment array type TableRaws<TTableName extends keyof TaylorDatabase> = {
export const getAttachmentUrl = ( [K in keyof TaylorDatabase[TTableName]]: TaylorColumnRaw<
attachments: AttachmentColumnValue[] | undefined | null, TaylorDatabase[TTableName][K]
): string | null => { >;
if (isEmpty(attachments) || !attachments?.[0]) return null;
const attachment = attachments[0];
return `${process.env.TAYLOR_MEDIA_URL}/${attachment.url}`;
}; };
// Helper to get link select name (link to selectTable returns object with name) const getAttachmentUrl = (urls: string[] | undefined): string | null => {
export const getLinkSelectName = ( if (!urls?.length) return null;
link: { name: string } | undefined | null,
): string | null => {
return link?.name || null;
};
// Helper to get multiple link select names (for arrays of links) const [url] = urls;
export const getLinkSelectNames = ( if (!url) return null;
links: Array<{ name: string }> | undefined | null,
): string[] => { if (/^https?:\/\//.test(url)) {
if (!links || isEmpty(links)) return []; return url;
return links.map((link) => link.name); }
return process.env.TAYLOR_MEDIA_URL
? `${process.env.TAYLOR_MEDIA_URL}/${url}`
: url;
}; };
// Presenters for TaylorDB query builder results (direct array format, no wrapper) // Presenters for TaylorDB query builder results (direct array format, no wrapper)
@ -53,13 +54,9 @@ export const presentJobsFromTaylor = (
return jobs.map((job, index) => ({ return jobs.map((job, index) => ({
id: index + 1, id: index + 1,
name: job.zagolovok || '', name: job.zagolovok || '',
// tegi is a LinkColumnType, so it returns objects when loaded with .with() tags: job.tegi || [],
tags: Array.isArray(job.tegi) location: job.lokaciya || null,
? (job.tegi as Array<{ name: string }>).map((tag) => tag.name) type: job.tip || null,
: [],
// tip and lokaciya are SingleSelectColumnType, which return arrays of strings
location: job.lokaciya?.[0] || null,
type: job.tip?.[0] || null,
})); }));
}; };
@ -108,9 +105,7 @@ export const presentStationsFromTaylor = (
name: station.imya || '', name: station.imya || '',
description: station.opisanie || '', description: station.opisanie || '',
address: station.adress || '', address: station.adress || '',
// chasyRaboty and region are SingleSelectColumnType, which return arrays of strings workingHours: station.chasyRaboty || null,
workingHours: station.chasyRaboty?.[0] || null,
// Parse string coordinates to numbers
latitude: parseFloat(station.lat || '0') || 0, latitude: parseFloat(station.lat || '0') || 0,
longitude: parseFloat(station.long || '0') || 0, longitude: parseFloat(station.long || '0') || 0,
carWash: station.avtomojka || false, carWash: station.avtomojka || false,
@ -122,7 +117,7 @@ export const presentStationsFromTaylor = (
electricCharge: station.zaryadnayaStanciya || false, electricCharge: station.zaryadnayaStanciya || false,
miniMarket: station.miniMarket || false, miniMarket: station.miniMarket || false,
toilet: station.tualet || false, toilet: station.tualet || false,
region: station.region?.[0] || null, region: station.region || null,
image: getAttachmentUrl(station.foto), image: getAttachmentUrl(station.foto),
})); }));
}; };

View File

@ -30,36 +30,16 @@ export async function fetchMainPageContent(): Promise<MainPageData> {
await taylorQueryBuilder await taylorQueryBuilder
.batch([ .batch([
// Fetch partners // Fetch partners
taylorQueryBuilder taylorQueryBuilder.selectFrom('partnyory').selectAll(),
.selectFrom('partnyory')
.selectAll()
.with({
izobrozhenie: (qb) => qb.selectAll(),
}),
// Fetch jobs // Fetch jobs
taylorQueryBuilder taylorQueryBuilder.selectFrom('vakansii').selectAll(),
.selectFrom('vakansii')
.selectAll()
.with({
tegi: (qb) => qb.select(['name']),
}),
// Fetch discounts // Fetch discounts
taylorQueryBuilder taylorQueryBuilder.selectFrom('akcii').selectAll(),
.selectFrom('akcii')
.selectAll()
.with({
foto: (qb) => qb.selectAll(),
}),
// Fetch stations // Fetch stations
taylorQueryBuilder taylorQueryBuilder.selectFrom('azs').selectAll(),
.selectFrom('azs')
.selectAll()
.with({
foto: (qb) => qb.selectAll(),
}),
]) ])
.execute(); .execute();
@ -82,12 +62,7 @@ export async function fetchAboutUsPageContent(): Promise<AboutUsPageData> {
await taylorQueryBuilder await taylorQueryBuilder
.batch([ .batch([
// Fetch team members // Fetch team members
taylorQueryBuilder taylorQueryBuilder.selectFrom('komanda').selectAll(),
.selectFrom('komanda')
.selectAll()
.with({
foto: (qb) => qb.selectAll(),
}),
// Fetch history items // Fetch history items
taylorQueryBuilder.selectFrom('istoriyaKompanii').selectAll(), taylorQueryBuilder.selectFrom('istoriyaKompanii').selectAll(),
@ -96,10 +71,7 @@ export async function fetchAboutUsPageContent(): Promise<AboutUsPageData> {
taylorQueryBuilder taylorQueryBuilder
.selectFrom('azs') .selectFrom('azs')
.selectAll() .selectAll()
.where('foto', 'isNotEmpty') .where('foto', 'isNotEmpty'),
.with({
foto: (qb) => qb.selectAll(),
}),
// Fetch reviews (filtered by published status) // Fetch reviews (filtered by published status)
taylorQueryBuilder taylorQueryBuilder
@ -126,9 +98,6 @@ export async function fetchCharityPageContent(): Promise<CharityPageData> {
const charitiesData = await taylorQueryBuilder const charitiesData = await taylorQueryBuilder
.selectFrom('blagotvoritelnyjFond') .selectFrom('blagotvoritelnyjFond')
.selectAll() .selectAll()
.with({
foto: (qb) => qb.selectAll(),
})
.execute(); .execute();
console.log('Loading charity page content...'); console.log('Loading charity page content...');
@ -145,9 +114,6 @@ export async function fetchCertificatesPageContent(): Promise<CertificatesPageDa
const certificatesData = await taylorQueryBuilder const certificatesData = await taylorQueryBuilder
.selectFrom('sertifikaty') .selectFrom('sertifikaty')
.selectAll() .selectAll()
.with({
foto: (qb) => qb.selectAll(),
})
.execute(); .execute();
console.log('Loading certificates page content...'); console.log('Loading certificates page content...');
@ -182,9 +148,6 @@ export async function fetchMediaContent(): Promise<
const mediaData = await taylorQueryBuilder const mediaData = await taylorQueryBuilder
.selectFrom('mediaKontentSajta') .selectFrom('mediaKontentSajta')
.selectAll() .selectAll()
.with({
foto: (qb) => qb.selectAll(),
})
.execute(); .execute();
console.log('Loading media content...'); console.log('Loading media content...');

View File

@ -4,423 +4,100 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {
attachmentField,
autoDateField,
autoNumberField,
checkboxField,
dateField,
defineTaylorSchema,
linkField,
numberField,
searchField,
selectField,
textField,
} from '@taylordb/query-builder';
import type { InferTaylorDatabase } from '@taylordb/query-builder';
interface FileInformation { export const taylorSchema = defineTaylorSchema({
fieldname: string; attachmentTable: {
originalname: string; id: autoNumberField(),
encoding: string; name: textField({ required: true }),
mimetype: string; metadata: textField({ required: true }),
destination: string; size: numberField({ required: true }),
filename: string; fileType: textField({ required: true }),
path: string; url: textField({ required: true }),
size: number; searchText: searchField(),
format: string; },
width: number; collaborators: {
height: number; id: autoNumberField(),
} name: textField({ required: true }),
emailAddress: textField({ required: true }),
interface UploadResponse { avatar: textField({ required: true }),
collectionName: string; searchText: searchField(),
fileInformation: FileInformation; },
metadata: { vakansii: {
thumbnails: any[]; id: autoNumberField(),
clips: any[]; createdAt: autoDateField(),
}; updatedAt: autoDateField(),
baseId: string; searchText: searchField(),
storageAdaptor: string; zagolovok: textField({ required: false }),
_id: string; tip: selectField({
__v: number; required: false,
} mode: 'single',
options: ['Офис', 'Заправки'] as const,
export interface AttachmentColumnValue { }),
url: string; lokaciya: selectField({
fileType: string; required: false,
size: number; mode: 'single',
} options: ['Душанбе'] as const,
}),
export class Attachment { tegi: selectField({
public readonly collectionName: string; required: false,
public readonly fileInformation: FileInformation; mode: 'multi',
public readonly metadata: { thumbnails: any[]; clips: any[] }; options: ['Полный день', 'Опыт от 1 года', 'Мужчины'] as const,
public readonly baseId: string; }),
public readonly storageAdaptor: string; },
public readonly _id: string; partnyory: {
id: autoNumberField(),
constructor(data: UploadResponse) { createdAt: autoDateField(),
this.collectionName = data.collectionName; updatedAt: autoDateField(),
this.fileInformation = data.fileInformation; searchText: searchField(),
this.metadata = data.metadata; nazvanie: textField({ required: false }),
this.baseId = data.baseId; tt: linkField({
this.storageAdaptor = data.storageAdaptor; linkedTo: 'ff',
this._id = data._id; required: false
} }),
izobrozhenie: attachmentField({ required: false }),
toColumnValue(): AttachmentColumnValue { },
return { azs: {
url: this.fileInformation.path, id: autoNumberField(),
fileType: this.fileInformation.mimetype, createdAt: autoDateField(),
size: this.fileInformation.size, updatedAt: autoDateField(),
}; searchText: searchField(),
} imya: textField({ required: false }),
} adress: textField({ required: false }),
opisanie: textField({ required: false }),
type IsWithinOperatorValue = chasyRaboty: selectField({
| 'pastWeek' required: false,
| 'pastMonth' mode: 'single',
| 'pastYear' options: ['Круглосуточно'] as const,
| 'nextWeek' }),
| 'nextMonth' lat: textField({ required: false }),
| 'nextYear' long: textField({ required: false }),
| 'daysFromNow' avtomojka: checkboxField({ required: false }),
| 'daysAgo' dt: checkboxField({ required: false }),
| 'currentWeek' ai92: checkboxField({ required: false }),
| 'currentMonth' ai95: checkboxField({ required: false }),
| 'currentYear'; z100: checkboxField({ required: false }),
propan: checkboxField({ required: false }),
type DefaultDateFilterValue = zaryadnayaStanciya: checkboxField({ required: false }),
| ( miniMarket: checkboxField({ required: false }),
| 'today' tualet: checkboxField({ required: false }),
| 'tomorrow' region: selectField({
| 'yesterday' required: false,
| 'oneWeekAgo' mode: 'single',
| 'oneWeekFromNow' options: [
| 'oneMonthAgo'
| 'oneMonthFromNow'
)
| ['exactDay' | 'exactTimestamp', string]
| ['daysAgo' | 'daysFromNow', number];
type DateFilters = {
'=': DefaultDateFilterValue;
'!=': DefaultDateFilterValue;
'<': DefaultDateFilterValue;
'>': DefaultDateFilterValue;
'<=': DefaultDateFilterValue;
'>=': DefaultDateFilterValue;
isWithIn:
| IsWithinOperatorValue
| { value: 'daysAgo' | 'daysFromNow'; date: number };
isEmpty: boolean;
isNotEmpty: boolean;
};
type DateAggregations = {
empty: number;
filled: number;
unique: number;
percentEmpty: number;
percentFilled: number;
percentUnique: number;
min: number | null;
max: number | null;
daysRange: number | null;
monthRange: number | null;
};
type TextFilters = {
'=': string;
'!=': string;
caseEqual: string;
hasAnyOf: string[];
contains: string;
startsWith: string;
endsWith: string;
doesNotContain: string;
isEmpty: never;
isNotEmpty: never;
};
type LinkFilters = {
hasAnyOf: number[];
hasAllOf: number[];
isExactly: number[];
'=': number;
hasNoneOf: number[];
contains: string;
doesNotContain: string;
isEmpty: never;
isNotEmpty: never;
};
type SelectFilters<O extends readonly string[]> = {
hasAnyOf: O[number][];
hasAllOf: O[number][];
isExactly: O[number][];
'=': O[number];
hasNoneOf: O[number][];
contains: string;
doesNotContain: string;
isEmpty: never;
isNotEmpty: never;
};
type LinkAggregations = {
empty: number;
filled: number;
percentEmpty: number;
percentFilled: number;
};
type NumberFilters = {
'=': number;
'!=': number;
'>': number;
'>=': number;
'<': number;
'<=': number;
hasAnyOf: number[];
hasNoneOf: number[];
isEmpty: never;
isNotEmpty: never;
};
type NumberAggregations = {
sum: number;
average: number;
median: number;
min: number | null;
max: number | null;
range: number;
standardDeviation: number;
histogram: Record<string, number>;
empty: number;
filled: number;
unique: number;
percentEmpty: number;
percentFilled: number;
percentUnique: number;
};
type CheckboxFilters = {
'=': number;
};
/**
*
* Column types
*
*/
export type ColumnType<
S,
U,
I,
R extends boolean,
F extends { [key: string]: any } = object,
A extends { [key: string]: any } = object,
> = {
raw: S;
insert: I;
update: U;
filters: F;
aggregations: A;
isRequired: R;
};
export type DateColumnType<R extends boolean> = ColumnType<
string,
string,
string,
R,
DateFilters,
DateAggregations
>;
export type TextColumnType<R extends boolean> = ColumnType<
string,
string,
string,
R,
TextFilters
>;
export type ALinkColumnType<
T extends string,
S,
U,
I,
R extends boolean,
F extends { [key: string]: any } = LinkFilters,
A extends LinkAggregations = LinkAggregations,
> = ColumnType<S, U, I, R, F, A> & {
linkedTo: T;
};
export type LinkColumnType<
T extends string,
R extends boolean,
> = ALinkColumnType<
T,
object,
number | number[] | { newIds: number[]; deletedIds: number[] },
number | number[],
R
>;
export type AttachmentColumnType<R extends boolean> = ALinkColumnType<
'attachmentTable',
AttachmentColumnValue[],
Attachment[] | { newIds: number[]; deletedIds: number[] } | number[],
Attachment[] | number[],
R
>;
export type NumberColumnType<R extends boolean> = ColumnType<
number,
number,
number,
R,
NumberFilters,
NumberAggregations
>;
export type CheckboxColumnType<R extends boolean> = ColumnType<
boolean,
boolean,
boolean,
R,
CheckboxFilters
>;
export type AutoGeneratedNumberColumnType = ColumnType<
number,
never,
never,
false,
NumberFilters,
NumberAggregations
>;
export type AutoGeneratedDateColumnType = ColumnType<
string,
never,
never,
false,
DateFilters,
DateAggregations
>;
export type SingleSelectColumnType<
O extends readonly string[],
R extends boolean,
> = ALinkColumnType<
'selectTable',
O[number],
O[number] | O[number][],
O[number] | O[number][],
R,
SelectFilters<O>
>;
export type TableRaws<T extends keyof TaylorDatabase> = {
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
infer S,
any,
any,
infer R,
any,
any
>
? R extends true
? S
: S | undefined
: never;
};
export type TableInserts<T extends keyof TaylorDatabase> = {
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
any,
infer I,
any,
infer R,
any,
any
>
? R extends true
? I
: I | undefined
: never;
};
export type TableUpdates<T extends keyof TaylorDatabase> = {
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
any,
any,
infer U,
any,
any,
any
>
? U
: never;
};
export type SelectTable = {
id: AutoGeneratedNumberColumnType;
name: TextColumnType<true>;
color: TextColumnType<true>;
};
export type AttachmentTable = {
id: AutoGeneratedNumberColumnType;
name: TextColumnType<true>;
metadata: TextColumnType<true>;
size: NumberColumnType<true>;
fileType: TextColumnType<true>;
url: TextColumnType<true>;
};
export type CollaboratorsTable = {
id: AutoGeneratedNumberColumnType;
name: TextColumnType<true>;
emailAddress: TextColumnType<true>;
avatar: TextColumnType<true>;
};
export type TaylorDatabase = {
/**
*
*
* Internal tables, these tables can not be queried directly.
*
*/
selectTable: SelectTable;
attachmentTable: AttachmentTable;
collaboratorsTable: CollaboratorsTable;
vakansii: VakansiiTable;
partnyory: PartnyoryTable;
azs: AzsTable;
akcii: AkciiTable;
istoriyaKompanii: IstoriyaKompaniiTable;
komanda: KomandaTable;
otzyvy: OtzyvyTable;
tekstovyjKontentSajta: TekstovyjKontentSajtaTable;
sertifikaty: SertifikatyTable;
mediaKontentSajta: MediaKontentSajtaTable;
blagotvoritelnyjFond: BlagotvoritelnyjFondTable;
};
export const VakansiiTipOptions = ['Офис', 'Заправки'] as const;
export const VakansiiLokaciyaOptions = ['Душанбе'] as const;
type VakansiiTable = {
id: NumberColumnType<false>;
createdAt: AutoGeneratedDateColumnType;
updatedAt: AutoGeneratedDateColumnType;
zagolovok: TextColumnType<false>;
tip: SingleSelectColumnType<typeof VakansiiTipOptions, false>;
lokaciya: SingleSelectColumnType<typeof VakansiiLokaciyaOptions, false>;
tegi: LinkColumnType<'selectTable', false>;
};
type PartnyoryTable = {
id: NumberColumnType<false>;
createdAt: AutoGeneratedDateColumnType;
updatedAt: AutoGeneratedDateColumnType;
nazvanie: TextColumnType<false>;
izobrozhenie: AttachmentColumnType<false>;
};
export const AzsChasyRabotyOptions = ['Круглосуточно'] as const;
export const AzsRegionOptions = [
'Душанбе', 'Душанбе',
'Бохтар', 'Бохтар',
'Худжанд', 'Худжанд',
@ -435,114 +112,127 @@ export const AzsRegionOptions = [
'Исфара', 'Исфара',
'Мастчох', 'Мастчох',
'Хисор', 'Хисор',
] as const; ] as const,
}),
type AzsTable = { foto: attachmentField({ required: false }),
id: NumberColumnType<false>; },
createdAt: AutoGeneratedDateColumnType; akcii: {
updatedAt: AutoGeneratedDateColumnType; id: autoNumberField(),
imya: TextColumnType<false>; createdAt: autoDateField(),
adress: TextColumnType<false>; updatedAt: autoDateField(),
opisanie: TextColumnType<false>; searchText: searchField(),
chasyRaboty: SingleSelectColumnType<typeof AzsChasyRabotyOptions, false>; zagolovok: textField({ required: false }),
lat: TextColumnType<false>; opisanie: textField({ required: false }),
long: TextColumnType<false>; do: dateField({ required: false }),
avtomojka: CheckboxColumnType<false>; foto: attachmentField({ required: false }),
dt: CheckboxColumnType<false>; },
ai92: CheckboxColumnType<false>; istoriyaKompanii: {
ai95: CheckboxColumnType<false>; id: autoNumberField(),
z100: CheckboxColumnType<false>; createdAt: autoDateField(),
propan: CheckboxColumnType<false>; updatedAt: autoDateField(),
zaryadnayaStanciya: CheckboxColumnType<false>; searchText: searchField(),
miniMarket: CheckboxColumnType<false>; zagolovok: textField({ required: false }),
tualet: CheckboxColumnType<false>; god: numberField({ required: false }),
region: SingleSelectColumnType<typeof AzsRegionOptions, false>; opisanie: textField({ required: false }),
foto: AttachmentColumnType<false>; },
}; komanda: {
type AkciiTable = { id: autoNumberField(),
id: NumberColumnType<false>; createdAt: autoDateField(),
createdAt: AutoGeneratedDateColumnType; updatedAt: autoDateField(),
updatedAt: AutoGeneratedDateColumnType; searchText: searchField(),
zagolovok: TextColumnType<false>; polnoeImya: textField({ required: false }),
opisanie: TextColumnType<false>; foto: attachmentField({ required: false }),
do: DateColumnType<false>; zvanie: textField({ required: false }),
foto: AttachmentColumnType<false>; },
}; otzyvy: {
type IstoriyaKompaniiTable = { id: autoNumberField(),
id: NumberColumnType<false>; createdAt: autoDateField(),
createdAt: AutoGeneratedDateColumnType; updatedAt: autoDateField(),
updatedAt: AutoGeneratedDateColumnType; searchText: searchField(),
zagolovok: TextColumnType<false>; polnoeImya: textField({ required: false }),
god: NumberColumnType<false>; otzyv: textField({ required: false }),
opisanie: TextColumnType<false>; rejting: numberField({ required: false }),
}; status: selectField({
type KomandaTable = { required: false,
id: NumberColumnType<false>; mode: 'single',
createdAt: AutoGeneratedDateColumnType; options: ['Опубликовано', 'Не публиковать'] as const,
updatedAt: AutoGeneratedDateColumnType; }),
polnoeImya: TextColumnType<false>; },
foto: AttachmentColumnType<false>; tekstovyjKontentSajta: {
zvanie: TextColumnType<false>; id: autoNumberField(),
}; createdAt: autoDateField(),
updatedAt: autoDateField(),
export const OtzyvyStatusOptions = ['Опубликовано', 'Не публиковать'] as const; searchText: searchField(),
klyuchNeIzmenyat: textField({ required: true }),
type OtzyvyTable = { znachenie: textField({ required: true }),
id: NumberColumnType<false>; opisanie: selectField({
createdAt: AutoGeneratedDateColumnType; required: false,
updatedAt: AutoGeneratedDateColumnType; mode: 'multi',
polnoeImya: TextColumnType<false>; options: [
otzyv: TextColumnType<false>; 'Общая',
rejting: NumberColumnType<false>; 'Домашняя страница',
status: SingleSelectColumnType<typeof OtzyvyStatusOptions, false>; 'О нас',
}; 'Благотворительность',
type TekstovyjKontentSajtaTable = { 'Клиенты',
id: NumberColumnType<false>; 'Почты',
createdAt: AutoGeneratedDateColumnType; 'Соц сети',
updatedAt: AutoGeneratedDateColumnType; 'Карты',
klyuchNeIzmenyat: TextColumnType<true>; 'Лояльность',
znachenie: TextColumnType<true>; 'Авторизация',
opisanie: LinkColumnType<'selectTable', false>; 'Сертификаты',
}; 'Бонусный клиент',
type SertifikatyTable = { 'Корпоративный клиент',
id: NumberColumnType<false>; 'Транзакции',
createdAt: AutoGeneratedDateColumnType; ] as const,
updatedAt: AutoGeneratedDateColumnType; }),
nazvanie: TextColumnType<false>; },
opisanie: TextColumnType<false>; sertifikaty: {
dataVydachi: DateColumnType<false>; id: autoNumberField(),
dejstvitelenDo: DateColumnType<false>; createdAt: autoDateField(),
foto: AttachmentColumnType<false>; updatedAt: autoDateField(),
}; searchText: searchField(),
nazvanie: textField({ required: false }),
export const MediaKontentSajtaStranicaOptions = [ opisanie: textField({ required: false }),
dataVydachi: dateField({ required: false }),
dejstvitelenDo: dateField({ required: false }),
foto: attachmentField({ required: false }),
},
mediaKontentSajta: {
id: autoNumberField(),
createdAt: autoDateField(),
updatedAt: autoDateField(),
searchText: searchField(),
mestopolozheniya: textField({ required: false }),
klyuchNeIzmenyat: textField({ required: true }),
foto: attachmentField({ required: false }),
stranica: selectField({
required: false,
mode: 'single',
options: [
'Главная', 'Главная',
'О нас', 'О нас',
'Благотворительность', 'Благотворительность',
'Общая', 'Общая',
'Клиенты', 'Клиенты',
'Программа лояльности', 'Программа лояльности',
] as const; ] as const,
}),
},
blagotvoritelnyjFond: {
id: autoNumberField(),
createdAt: autoDateField(),
updatedAt: autoDateField(),
searchText: searchField(),
zagolovok: textField({ required: false }),
opisanie: textField({ required: false }),
data: dateField({ required: false }),
lokaciya: textField({ required: false }),
foto: attachmentField({ required: false }),
},
});
type MediaKontentSajtaTable = { /** Generic type for plugin actions */
id: NumberColumnType<false>; export type PluginActionType<I, O> = { input: I; result: O };
createdAt: AutoGeneratedDateColumnType; export type TaylorDatabase = InferTaylorDatabase<typeof taylorSchema> & {
updatedAt: AutoGeneratedDateColumnType; _plugins: {};
mestopolozheniya: TextColumnType<false>;
klyuchNeIzmenyat: TextColumnType<true>;
foto: AttachmentColumnType<false>;
stranica: SingleSelectColumnType<
typeof MediaKontentSajtaStranicaOptions,
false
>;
};
type BlagotvoritelnyjFondTable = {
id: NumberColumnType<false>;
createdAt: AutoGeneratedDateColumnType;
updatedAt: AutoGeneratedDateColumnType;
zagolovok: TextColumnType<false>;
opisanie: TextColumnType<false>;
data: DateColumnType<false>;
lokaciya: TextColumnType<false>;
foto: AttachmentColumnType<false>;
}; };