diff --git a/package-lock.json b/package-lock.json index ae84951b..1f4f4185 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@datalens-tech/datalens-us", - "version": "0.0.0", + "version": "0.360.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@datalens-tech/datalens-us", - "version": "0.0.0", + "version": "0.360.0", "license": "Apache-2.0", "dependencies": { "@asteasolutions/zod-to-openapi": "^7.3.0", diff --git a/package.json b/package.json index 3e75e804..1b81ab33 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@datalens-tech/datalens-us", "description": "United Storage", - "version": "0.0.0", + "version": "0.360.0", "private": true, "author": "DataLens Team ", "license": "Apache-2.0", diff --git a/src/controllers/test-graph.ts b/src/controllers/test-graph.ts new file mode 100644 index 00000000..02e3af88 --- /dev/null +++ b/src/controllers/test-graph.ts @@ -0,0 +1,25 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {DEFAULT_QUERY_TIMEOUT} from '../const'; +import {Order} from '../db/models-graph/order'; + +export default async function testGraphController(_: Request, res: Response) { + const result = await Order.query(Order.replica) + .withGraphJoined('[customer]') + .timeout(DEFAULT_QUERY_TIMEOUT); + + res.status(200).send(result); + + // const result = await Order.query(Order.replica) + // .withGraphJoined('[customer, shipments.[product]]') + // .timeout(DEFAULT_QUERY_TIMEOUT); + + // res.status(200).send(result); + + // const result = await Order.query(Order.replica) + // .withGraphJoined('[customer, shipments.[product.[orders]], products.[orders]]') + // .first() + // .timeout(DEFAULT_QUERY_TIMEOUT); + + res.status(200).send(result); +} diff --git a/src/controllers/test-presentations.ts b/src/controllers/test-presentations.ts new file mode 100644 index 00000000..d500b8c5 --- /dev/null +++ b/src/controllers/test-presentations.ts @@ -0,0 +1,22 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {DEFAULT_QUERY_TIMEOUT} from '../const'; +import {Order, OrderColumn} from '../db/models-presentations/order'; +import {JoinedOrderCustomer} from '../db/models-presentations/order/presentations/joined-order-customer'; +// import {JoinedOrderCustomerShipments} from '../db/models-presentations/order/presentations/joined-order-customer-shipments'; +// import {JoinedOrderCustomerShipmentsProducts} from '../db/models-presentations/order/presentations/joined-order-customer-shipments-products'; +// import {PartialOrder} from '../db/models-presentations/order/presentations/partial-order'; + +export default async function testPresentationsController(_: Request, res: Response) { + const result = await JoinedOrderCustomer.query(Order.replica) + .where({ + [`${Order.tableName}.${OrderColumn.OrderId}`]: '1988457138476811343', + }) + // .findOne({ + // orderId: '1988457138476811343', + // }) + .first() + .timeout(DEFAULT_QUERY_TIMEOUT); + + res.status(200).send(result); +} diff --git a/src/db/SCHEMA.md b/src/db/SCHEMA.md new file mode 100644 index 00000000..e69107e3 --- /dev/null +++ b/src/db/SCHEMA.md @@ -0,0 +1,37 @@ +```sql +CREATE TABLE orders ( + order_id BIGINT DEFAULT get_id() PRIMARY KEY, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + customer_id BIGINT NOT NULL, + + CONSTRAINT fk_customer + FOREIGN KEY (customer_id) + REFERENCES customers(customer_id) + ON DELETE CASCADE +); + +CREATE TABLE shipments ( + shipment_id BIGINT DEFAULT get_id() PRIMARY KEY, + order_id BIGINT NOT NULL, + product_id BIGINT NOT NULL, + + CONSTRAINT fk_order + FOREIGN KEY (order_id) + REFERENCES orders(order_id) + ON DELETE CASCADE, + CONSTRAINT fk_product + FOREIGN KEY (product_id) + REFERENCES products(product_id) + ON DELETE RESTRICT +); + +CREATE TABLE customers ( + customer_id BIGINT DEFAULT get_id() PRIMARY KEY, + name TEXT NOT NULL +); + +CREATE TABLE products ( + product_id BIGINT DEFAULT get_id() PRIMARY KEY, + name TEXT NOT NULL +); +``` \ No newline at end of file diff --git a/src/db/models-graph/customer/index.ts b/src/db/models-graph/customer/index.ts new file mode 100644 index 00000000..98cc166b --- /dev/null +++ b/src/db/models-graph/customer/index.ts @@ -0,0 +1,30 @@ +import {Model} from '../..'; +import {Order} from '../order'; + +export class Customer extends Model { + static get tableName() { + return 'customers'; + } + + static get idColumn() { + return 'customerId'; + } + + static get relationMappings() { + return { + orders: { + relation: Model.HasManyRelation, + modelClass: Order, + join: { + from: `${Customer.tableName}.customerId`, + to: `${Order.tableName}.customerId`, + }, + }, + }; + } + + customerId!: string; + name!: string; + + orders?: Order[]; +} diff --git a/src/db/models-graph/order/index.ts b/src/db/models-graph/order/index.ts new file mode 100644 index 00000000..c4db667d --- /dev/null +++ b/src/db/models-graph/order/index.ts @@ -0,0 +1,57 @@ +import {Model} from '../..'; +import {Customer} from '../customer'; +import {Product} from '../product'; +import {Shipment} from '../shipment'; + +export class Order extends Model { + static get tableName() { + return 'orders'; + } + + static get idColumn() { + return 'orderId'; + } + + static get relationMappings() { + return { + customer: { + relation: Model.BelongsToOneRelation, + modelClass: Customer, + join: { + from: `${Order.tableName}.customerId`, + to: `${Customer.tableName}.customerId`, + }, + }, + + shipments: { + relation: Model.HasManyRelation, + modelClass: Shipment, + join: { + from: `${Order.tableName}.orderId`, + to: `${Shipment.tableName}.orderId`, + }, + }, + + products: { + relation: Model.ManyToManyRelation, + modelClass: Product, + join: { + from: `${Order.tableName}.orderId`, + through: { + from: `${Shipment.tableName}.orderId`, + to: `${Shipment.tableName}.productId`, + }, + to: `${Product.tableName}.productId`, + }, + }, + }; + } + + orderId!: string; + createdAt!: string; + customerId!: string; + + customer?: Customer; + shipments?: Shipment[]; + products?: Product[]; +} diff --git a/src/db/models-graph/product/index.ts b/src/db/models-graph/product/index.ts new file mode 100644 index 00000000..6f8f6fb1 --- /dev/null +++ b/src/db/models-graph/product/index.ts @@ -0,0 +1,45 @@ +import {Model} from '../..'; +import {Order} from '../order'; +import {Shipment} from '../shipment'; + +export class Product extends Model { + static get tableName() { + return 'products'; + } + + static get idColumn() { + return 'productId'; + } + + static get relationMappings() { + return { + shipments: { + relation: Model.HasManyRelation, + modelClass: Shipment, + join: { + from: `${Product.tableName}.productId`, + to: `${Shipment.tableName}.productId`, + }, + }, + + orders: { + relation: Model.ManyToManyRelation, + modelClass: Order, + join: { + from: `${Product.tableName}.productId`, + through: { + from: `${Shipment.tableName}.productId`, + to: `${Shipment.tableName}.orderId`, + }, + to: `${Order.tableName}.orderId`, + }, + }, + }; + } + + productId!: string; + name!: string; + + shipments?: Shipment[]; + orders?: Order[]; +} diff --git a/src/db/models-graph/shipment/index.ts b/src/db/models-graph/shipment/index.ts new file mode 100644 index 00000000..904e0b1f --- /dev/null +++ b/src/db/models-graph/shipment/index.ts @@ -0,0 +1,42 @@ +import {Model} from '../..'; +import {Order} from '../order'; +import {Product} from '../product'; + +export class Shipment extends Model { + static get tableName() { + return 'shipments'; + } + + static get idColumn() { + return 'shipmentId'; + } + + static get relationMappings() { + return { + order: { + relation: Model.BelongsToOneRelation, + modelClass: Order, + join: { + from: `${Shipment.tableName}.orderId`, + to: `${Order.tableName}.orderId`, + }, + }, + + product: { + relation: Model.BelongsToOneRelation, + modelClass: Product, + join: { + from: `${Shipment.tableName}.productId`, + to: `${Product.tableName}.productId`, + }, + }, + }; + } + + shipmentId!: string; + orderId!: string; + productId!: string; + + order?: Order; + product?: Product; +} diff --git a/src/db/models-presentations/customer/index.ts b/src/db/models-presentations/customer/index.ts new file mode 100644 index 00000000..e856a35a --- /dev/null +++ b/src/db/models-presentations/customer/index.ts @@ -0,0 +1,19 @@ +import {Model} from '../..'; + +export const CustomerColumn = { + CustomerId: 'customerId', + Name: 'name', +} as const; + +export class Customer extends Model { + static get tableName() { + return 'customers'; + } + + static get idColumn() { + return CustomerColumn.CustomerId; + } + + [CustomerColumn.CustomerId]!: string; + [CustomerColumn.Name]!: string; +} diff --git a/src/db/models-presentations/order/index.ts b/src/db/models-presentations/order/index.ts new file mode 100644 index 00000000..df611887 --- /dev/null +++ b/src/db/models-presentations/order/index.ts @@ -0,0 +1,21 @@ +import {Model} from '../..'; + +export const OrderColumn = { + OrderId: 'orderId', + CreatedAt: 'createdAt', + CustomerId: 'customerId', +} as const; + +export class Order extends Model { + static get tableName() { + return 'orders'; + } + + static get idColumn() { + return OrderColumn.OrderId; + } + + [OrderColumn.OrderId]!: string; + [OrderColumn.CreatedAt]!: string; + [OrderColumn.CustomerId]!: string; +} diff --git a/src/db/models-presentations/order/presentations/joined-order-customer-shipments-products.ts b/src/db/models-presentations/order/presentations/joined-order-customer-shipments-products.ts new file mode 100644 index 00000000..6a6f3c3c --- /dev/null +++ b/src/db/models-presentations/order/presentations/joined-order-customer-shipments-products.ts @@ -0,0 +1,40 @@ +import type {Knex} from 'knex'; +import {QueryBuilder, TransactionOrKnex, raw} from 'objection'; + +import {Customer} from '../../customer'; +import {Product, ProductColumn} from '../../product'; +import {Shipment, ShipmentColumn} from '../../shipment'; +import {Order} from '../index'; + +import {JoinedOrderCustomerShipments} from './joined-order-customer-shipments'; + +export class JoinedOrderCustomerShipmentsProducts extends JoinedOrderCustomerShipments { + static _joinProducts(builder: Knex.JoinClause) { + builder.on( + `${Shipment.tableName}.${ShipmentColumn.ProductId}`, + `${Product.tableName}.${ProductColumn.ProductId}`, + ); + } + + static get _selectedColumns() { + return [ + ...super._selectedColumns, + raw(`${Product.tableName}.${ProductColumn.Name} AS product_name`), + ]; + } + + static query(trx: TransactionOrKnex) { + const query = Order.query(trx) + .select(this._selectedColumns) + .join(Customer.tableName, this._joinCustomer) + .rightJoin(Shipment.tableName, this._rightJoinShipments) + .join(Product.tableName, this._joinProducts); + + return query as QueryBuilder< + JoinedOrderCustomerShipmentsProducts, + JoinedOrderCustomerShipmentsProducts[] + >; + } + + productName!: Product[typeof ProductColumn.Name]; +} diff --git a/src/db/models-presentations/order/presentations/joined-order-customer-shipments.ts b/src/db/models-presentations/order/presentations/joined-order-customer-shipments.ts new file mode 100644 index 00000000..09c542fa --- /dev/null +++ b/src/db/models-presentations/order/presentations/joined-order-customer-shipments.ts @@ -0,0 +1,37 @@ +import type {Knex} from 'knex'; +import {QueryBuilder, TransactionOrKnex} from 'objection'; + +import {Customer} from '../../customer'; +import {Shipment, ShipmentColumn} from '../../shipment'; +import {Order, OrderColumn} from '../index'; + +import {JoinedOrderCustomer} from './joined-order-customer'; + +export class JoinedOrderCustomerShipments extends JoinedOrderCustomer { + static _rightJoinShipments(builder: Knex.JoinClause) { + builder.on( + `${Order.tableName}.${OrderColumn.OrderId}`, + `${Shipment.tableName}.${ShipmentColumn.OrderId}`, + ); + } + + static get _selectedColumns() { + return [ + ...super._selectedColumns, + `${Shipment.tableName}.${ShipmentColumn.ShipmentId}`, + `${Shipment.tableName}.${ShipmentColumn.ProductId}`, + ]; + } + + static query(trx: TransactionOrKnex) { + const query = Order.query(trx) + .select(this._selectedColumns) + .join(Customer.tableName, this._joinCustomer) + .rightJoin(Shipment.tableName, this._rightJoinShipments); + + return query as QueryBuilder; + } + + [ShipmentColumn.ShipmentId]!: Shipment[typeof ShipmentColumn.ShipmentId]; + [ShipmentColumn.ProductId]!: Shipment[typeof ShipmentColumn.ProductId]; +} diff --git a/src/db/models-presentations/order/presentations/joined-order-customer.ts b/src/db/models-presentations/order/presentations/joined-order-customer.ts new file mode 100644 index 00000000..d02f4df7 --- /dev/null +++ b/src/db/models-presentations/order/presentations/joined-order-customer.ts @@ -0,0 +1,46 @@ +import type {Knex} from 'knex'; +import {QueryBuilder, TransactionOrKnex, raw} from 'objection'; + +import {Model} from '../../..'; +import {Customer, CustomerColumn} from '../../customer'; +import {Order, OrderColumn} from '../index'; + +export class JoinedOrderCustomer extends Model { + static get tableName() { + return Order.tableName; + } + + static get idColumn() { + return Order.idColumn; + } + + static _joinCustomer(builder: Knex.JoinClause) { + builder.on( + `${Order.tableName}.${OrderColumn.CustomerId}`, + `${Customer.tableName}.${CustomerColumn.CustomerId}`, + ); + } + + static get _selectedColumns() { + return [ + `${Order.tableName}.${OrderColumn.OrderId}`, + `${Order.tableName}.${OrderColumn.CustomerId}`, + `${Order.tableName}.${OrderColumn.CreatedAt}`, + raw(`${Customer.tableName}.${CustomerColumn.Name} AS customer_name`), + ]; + } + + static query(trx: TransactionOrKnex) { + const query = Order.query(trx) + .select(this._selectedColumns) + .join(Customer.tableName, this._joinCustomer); + + return query as QueryBuilder; + } + + [OrderColumn.OrderId]!: Order[typeof OrderColumn.OrderId]; + [OrderColumn.CustomerId]!: Order[typeof OrderColumn.CustomerId]; + [OrderColumn.CreatedAt]!: Order[typeof OrderColumn.CreatedAt]; + [CustomerColumn.Name]!: Customer[typeof CustomerColumn.Name]; + customerName!: string; +} diff --git a/src/db/models-presentations/order/presentations/partial-order.ts b/src/db/models-presentations/order/presentations/partial-order.ts new file mode 100644 index 00000000..5cb07500 --- /dev/null +++ b/src/db/models-presentations/order/presentations/partial-order.ts @@ -0,0 +1,29 @@ +import {QueryBuilder, TransactionOrKnex} from 'objection'; + +import {Model} from '../../..'; +import {Order, OrderColumn} from '../index'; + +export class PartialOrder extends Model { + static get tableName() { + return Order.tableName; + } + + static get idColumn() { + return Order.idColumn; + } + + static get _selectedColumns() { + return [ + `${Order.tableName}.${OrderColumn.OrderId}`, + `${Order.tableName}.${OrderColumn.CreatedAt}`, + ]; + } + + static query(trx: TransactionOrKnex) { + const query = Order.query(trx).select(this._selectedColumns); + return query as QueryBuilder; + } + + [OrderColumn.OrderId]!: Order[typeof OrderColumn.OrderId]; + [OrderColumn.CreatedAt]!: Order[typeof OrderColumn.CreatedAt]; +} diff --git a/src/db/models-presentations/product/index.ts b/src/db/models-presentations/product/index.ts new file mode 100644 index 00000000..fdd83895 --- /dev/null +++ b/src/db/models-presentations/product/index.ts @@ -0,0 +1,19 @@ +import {Model} from '../..'; + +export const ProductColumn = { + ProductId: 'productId', + Name: 'name', +} as const; + +export class Product extends Model { + static get tableName() { + return 'products'; + } + + static get idColumn() { + return 'productId'; + } + + [ProductColumn.ProductId]!: string; + [ProductColumn.Name]!: string; +} diff --git a/src/db/models-presentations/shipment/index.ts b/src/db/models-presentations/shipment/index.ts new file mode 100644 index 00000000..35b99ad1 --- /dev/null +++ b/src/db/models-presentations/shipment/index.ts @@ -0,0 +1,21 @@ +import {Model} from '../..'; + +export const ShipmentColumn = { + ShipmentId: 'shipmentId', + OrderId: 'orderId', + ProductId: 'productId', +} as const; + +export class Shipment extends Model { + static get tableName() { + return 'shipments'; + } + + static get idColumn() { + return 'shipmentId'; + } + + [ShipmentColumn.ShipmentId]!: string; + [ShipmentColumn.OrderId]!: string; + [ShipmentColumn.ProductId]!: string; +} diff --git a/src/db/models/new/entry/presentations/joined-entry-revision-favorite.ts b/src/db/models/new/entry/presentations/joined-entry-revision-favorite.ts new file mode 100644 index 00000000..a952b153 --- /dev/null +++ b/src/db/models/new/entry/presentations/joined-entry-revision-favorite.ts @@ -0,0 +1,51 @@ +import type {Knex} from 'knex'; +import {QueryBuilder, TransactionOrKnex, raw} from 'objection'; + +import {Entry, EntryColumn} from '../'; +import {Favorite, FavoriteColumn} from '../../favorite'; +import {RevisionModel as Revision, RevisionModelColumn as RevisionColumn} from '../../revision'; + +import {JoinedEntryRevision, RevisionBranch} from './joined-entry-revision'; + +export class JoinedEntryRevisionFavorite extends JoinedEntryRevision { + static _joinFavorite({userLogin}: {userLogin: string}) { + return (builder: Knex.JoinClause) => { + builder + .on( + `${Favorite.tableName}.${FavoriteColumn.EntryId}`, + `${Entry.tableName}.${EntryColumn.EntryId}`, + ) + .andOnIn(`${Favorite.tableName}.${FavoriteColumn.Login}`, [userLogin]); + }; + } + + static get _selectedColumns() { + return [ + ...super._selectedColumns, + raw( + `CASE WHEN ${Favorite.tableName}.entry_id IS NULL THEN FALSE ELSE TRUE END AS is_favorite`, + ) as unknown as string, + ]; + } + + static query( + trx: TransactionOrKnex, + {userLogin, revId, branch}: {userLogin: string; revId?: string; branch?: RevisionBranch}, + ) { + const query = Entry.query(trx) + .select(this._selectedColumns) + .join(Revision.tableName, this._joinRevision({revId, branch})) + .join(Favorite.tableName, this._joinFavorite({userLogin})); + + if (revId) { + query.where({[RevisionColumn.RevId]: revId}); + } + + return query as unknown as QueryBuilder< + JoinedEntryRevisionFavorite, + JoinedEntryRevisionFavorite[] + >; + } + + isFavorite!: boolean; +} diff --git a/src/db/models/new/entry/presentations/joined-entry-revision.ts b/src/db/models/new/entry/presentations/joined-entry-revision.ts new file mode 100644 index 00000000..087b2eee --- /dev/null +++ b/src/db/models/new/entry/presentations/joined-entry-revision.ts @@ -0,0 +1,122 @@ +import type {Knex} from 'knex'; +import {QueryBuilder, TransactionOrKnex, raw} from 'objection'; + +import {Entry, EntryColumn} from '../'; +import {Model} from '../../../..'; +import {RevisionModel as Revision, RevisionModelColumn as RevisionColumn} from '../../revision'; + +export type RevisionBranch = 'saved' | 'published'; + +export class JoinedEntryRevision extends Model { + static get tableName() { + return Entry.tableName; + } + + static get idColumn() { + return Entry.idColumn; + } + + static _joinRevision({revId, branch}: {revId?: string; branch?: RevisionBranch}) { + return (builder: Knex.JoinClause) => { + if (revId) { + builder.on( + `${Entry.tableName}.${EntryColumn.EntryId}`, + `${Revision.tableName}.${RevisionColumn.EntryId}`, + ); + } else if (branch === 'saved') { + builder.on( + `${Entry.tableName}.${EntryColumn.SavedId}`, + `${Revision.tableName}.${RevisionColumn.RevId}`, + ); + } else if (branch === 'published') { + builder.on( + `${Entry.tableName}.${EntryColumn.PublishedId}`, + `${Revision.tableName}.${RevisionColumn.RevId}`, + ); + } else { + builder.on( + raw(`COALESCE(??, ??)`, [ + `${Entry.tableName}.${EntryColumn.PublishedId}`, + `${Entry.tableName}.${EntryColumn.SavedId}`, + ]) as unknown as string, // TODO: fix type + `${Revision.tableName}.${RevisionColumn.RevId}`, + ); + } + }; + } + + static get _selectedColumns() { + return [ + `${Entry.tableName}.${EntryColumn.Scope}`, + `${Entry.tableName}.${EntryColumn.Type}`, + `${Entry.tableName}.${EntryColumn.Key}`, + `${Entry.tableName}.${EntryColumn.InnerMeta}`, + `${Entry.tableName}.${EntryColumn.CreatedBy}`, + `${Entry.tableName}.${EntryColumn.CreatedAt}`, + `${Entry.tableName}.${EntryColumn.IsDeleted}`, + `${Entry.tableName}.${EntryColumn.DeletedAt}`, + `${Entry.tableName}.${EntryColumn.Hidden}`, + `${Entry.tableName}.${EntryColumn.DisplayKey}`, + `${Entry.tableName}.${EntryColumn.EntryId}`, + `${Entry.tableName}.${EntryColumn.SavedId}`, + `${Entry.tableName}.${EntryColumn.PublishedId}`, + `${Entry.tableName}.${EntryColumn.TenantId}`, + `${Entry.tableName}.${EntryColumn.Name}`, + `${Entry.tableName}.${EntryColumn.SortName}`, + `${Entry.tableName}.${EntryColumn.Public}`, + `${Entry.tableName}.${EntryColumn.UnversionedData}`, + `${Entry.tableName}.${EntryColumn.WorkbookId}`, + `${Entry.tableName}.${EntryColumn.Mirrored}`, + + `${Revision.tableName}.${RevisionColumn.Data}`, + `${Revision.tableName}.${RevisionColumn.Meta}`, + `${Revision.tableName}.${RevisionColumn.UpdatedBy}`, + `${Revision.tableName}.${RevisionColumn.UpdatedAt}`, + `${Revision.tableName}.${RevisionColumn.RevId}`, + `${Revision.tableName}.${RevisionColumn.Links}`, + ]; + } + + static query( + trx: TransactionOrKnex, + {revId, branch}: {revId?: string; branch?: RevisionBranch} = {}, + ) { + const query = Entry.query(trx) + .select(this._selectedColumns) + .join(Revision.tableName, this._joinRevision({revId, branch})); + + if (revId) { + query.where({[RevisionColumn.RevId]: revId}); + } + + return query as unknown as QueryBuilder; + } + + [EntryColumn.Scope]!: Entry[typeof EntryColumn.Scope]; + [EntryColumn.Type]!: Entry[typeof EntryColumn.Type]; + [EntryColumn.Key]!: Entry[typeof EntryColumn.Key]; + [EntryColumn.InnerMeta]!: Entry[typeof EntryColumn.InnerMeta]; + [EntryColumn.CreatedBy]!: Entry[typeof EntryColumn.CreatedBy]; + [EntryColumn.CreatedAt]!: Entry[typeof EntryColumn.CreatedAt]; + [EntryColumn.IsDeleted]!: Entry[typeof EntryColumn.IsDeleted]; + [EntryColumn.DeletedAt]!: Entry[typeof EntryColumn.DeletedAt]; + [EntryColumn.Hidden]!: Entry[typeof EntryColumn.Hidden]; + [EntryColumn.DisplayKey]!: Entry[typeof EntryColumn.DisplayKey]; + [EntryColumn.EntryId]!: Entry[typeof EntryColumn.EntryId]; + [EntryColumn.SavedId]!: Entry[typeof EntryColumn.SavedId]; + [EntryColumn.PublishedId]!: Entry[typeof EntryColumn.PublishedId]; + [EntryColumn.TenantId]!: Entry[typeof EntryColumn.TenantId]; + [EntryColumn.Name]!: Entry[typeof EntryColumn.Name]; + [EntryColumn.SortName]!: Entry[typeof EntryColumn.SortName]; + [EntryColumn.Public]!: Entry[typeof EntryColumn.Public]; + [EntryColumn.UnversionedData]!: Entry[typeof EntryColumn.UnversionedData]; + [EntryColumn.WorkbookId]!: Entry[typeof EntryColumn.WorkbookId]; + [EntryColumn.Mirrored]!: Entry[typeof EntryColumn.Mirrored]; + + [RevisionColumn.Data]!: Nullable; + [RevisionColumn.Meta]!: Nullable; + [RevisionColumn.UpdatedBy]!: Nullable; + [RevisionColumn.UpdatedAt]!: Nullable; + [RevisionColumn.RevId]!: Nullable; + [RevisionColumn.Links]!: Nullable; +} diff --git a/src/db/models/new/favorite/index.ts b/src/db/models/new/favorite/index.ts index 0ca27fa2..cfc7926c 100644 --- a/src/db/models/new/favorite/index.ts +++ b/src/db/models/new/favorite/index.ts @@ -1,6 +1,14 @@ import {Model} from '../../..'; import {Entry} from '../entry'; +export const FavoriteColumn = { + EntryId: 'entryId', + TenantId: 'tenantId', + Login: 'login', + Alias: 'alias', + CreatedAt: 'createdAt', +} as const; + export class Favorite extends Model { static get tableName() { return 'favorites'; diff --git a/src/routes.ts b/src/routes.ts index e050fb02..a0516d6d 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -13,6 +13,8 @@ import locks from './controllers/locks'; import states from './controllers/states'; import structureItems from './controllers/structure-items'; import tenants from './controllers/tenants'; +import testGraphController from './controllers/test-graph'; +import testPresentationsController from './controllers/test-presentations'; import workbooks from './controllers/workbooks'; export type GetRoutesOptions = { @@ -35,6 +37,17 @@ export function getRoutes(_nodekit: NodeKit, options: GetRoutesOptions) { }); const routes = { + testGraph: makeRoute({ + route: 'GET /test-graph', + handler: testGraphController, + authPolicy: AuthPolicy.disabled, + }), + testPresentations: makeRoute({ + route: 'GET /test-presentations', + handler: testPresentationsController, + authPolicy: AuthPolicy.disabled, + }), + home: makeRoute({ route: 'GET /', handler: homeController,