Refactor module schema handling and add sync mechanism

Redesigned entity and index management with methods to streamline schema updates and added a sync flag to signal required DB syncs post-build. Enhanced test coverage and functionality for schema modifications, including support for additional fields.
This commit is contained in:
dswbx
2025-01-10 14:43:39 +01:00
parent 475563b5e1
commit a8c20d3675
11 changed files with 413 additions and 109 deletions

View File

@@ -1,8 +1,17 @@
import type { PrimaryFieldType } from "core";
import { EntityIndex, type EntityManager } from "data";
import { type Entity, EntityIndex, type EntityManager } from "data";
import { type FileUploadedEventData, Storage, type StorageAdapter } from "media";
import { Module } from "modules/Module";
import { type FieldSchema, boolean, datetime, entity, json, number, text } from "../data/prototype";
import {
type FieldSchema,
boolean,
datetime,
em,
entity,
json,
number,
text
} from "../data/prototype";
import { MediaController } from "./api/MediaController";
import { ADAPTERS, buildMediaSchema, type mediaConfigSchema, registry } from "./media-schema";
@@ -17,6 +26,7 @@ export class AppMedia extends Module<typeof mediaConfigSchema> {
private _storage?: Storage;
override async build() {
console.log("building");
if (!this.config.enabled) {
this.setBuilt();
return;
@@ -38,18 +48,13 @@ export class AppMedia extends Module<typeof mediaConfigSchema> {
this.setupListeners();
this.ctx.server.route(this.basepath, new MediaController(this).getController());
// @todo: add check for media entity
const mediaEntity = this.getMediaEntity();
if (!this.ctx.em.hasEntity(mediaEntity)) {
this.ctx.em.addEntity(mediaEntity);
}
const pathIndex = new EntityIndex(mediaEntity, [mediaEntity.field("path")!], true);
if (!this.ctx.em.hasIndex(pathIndex)) {
this.ctx.em.addIndex(pathIndex);
}
// @todo: check indices
const mediaEntity = this.getMediaEntity(true);
const name = mediaEntity.name as "media";
this.ensureSchema(
em({ [name]: mediaEntity }, ({ index }, { media }) => {
index(media).on(["path"], true).on(["reference"]);
})
);
} catch (e) {
console.error(e);
throw new Error(
@@ -94,13 +99,13 @@ export class AppMedia extends Module<typeof mediaConfigSchema> {
metadata: json()
};
getMediaEntity() {
getMediaEntity(forceCreate?: boolean): Entity<"media", typeof AppMedia.mediaFields> {
const entity_name = this.config.entity_name;
if (!this.em.hasEntity(entity_name)) {
return entity(entity_name, AppMedia.mediaFields, undefined, "system");
if (forceCreate || !this.em.hasEntity(entity_name)) {
return entity(entity_name as "media", AppMedia.mediaFields, undefined, "system");
}
return this.em.entity(entity_name);
return this.em.entity(entity_name) as any;
}
get em(): EntityManager {