1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-02 20:15:24 +02:00

feature: proper multi-tenant-support (#969)(WIP)

* update naming

* refactor tests to use shared structure

* shorten names

* add tools test case

* refactor to support multi-tenant

* set group_id on creation

* initial refactor for multitenant tags/cats

* spelling

* additional test case for same valued resources

* fix recipe update tests

* apply indexes to foreign keys

* fix performance regressions

* handle unknown exception

* utility decorator for function debugging

* migrate recipe_id to UUID

* GUID for recipes

* remove unused import

* move image functions into package

* move utilities to packages dir

* update import

* linter

* image image and asset routes

* update assets and images to use UUIDs

* fix migration base

* image asset test coverage

* use ids for categories and tag crud functions

* refactor recipe organizer test suite to reduce duplication

* add uuid serlization utility

* organizer base router

* slug routes testing and fixes

* fix postgres error

* adopt UUIDs

* move tags, categories, and tools under "organizers" umbrella

* update composite label

* generate ts types

* fix import error

* update frontend types

* fix type errors

* fix postgres errors

* fix #978

* add null check for title validation

* add note in docs on multi-tenancy
This commit is contained in:
Hayden 2022-02-13 12:23:42 -09:00 committed by GitHub
parent 9a82a172cb
commit c617251f4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 1866 additions and 1578 deletions

View file

@ -10,20 +10,20 @@ export const useStaticRoutes = () => {
const fullBase = serverBase + prefix;
// Methods to Generate reference urls for assets/images *
function recipeImage(recipeSlug: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeSlug}/images/original.webp?&rnd=${key}&version=${version}`;
function recipeImage(recipeId: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeId}/images/original.webp?&rnd=${key}&version=${version}`;
}
function recipeSmallImage(recipeSlug: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeSlug}/images/min-original.webp?&rnd=${key}&version=${version}`;
function recipeSmallImage(recipeId: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeId}/images/min-original.webp?&rnd=${key}&version=${version}`;
}
function recipeTinyImage(recipeSlug: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeSlug}/images/tiny-original.webp?&rnd=${key}&version=${version}`;
function recipeTinyImage(recipeId: string, version = "", key = 1) {
return `${fullBase}/media/recipes/${recipeId}/images/tiny-original.webp?&rnd=${key}&version=${version}`;
}
function recipeAssetPath(recipeSlug: string, assetName: string) {
return `${fullBase}/media/recipes/${recipeSlug}/assets/${assetName}`;
function recipeAssetPath(recipeId: string, assetName: string) {
return `${fullBase}/media/recipes/${recipeId}/assets/${assetName}`;
}
return {

View file

@ -12,11 +12,11 @@ export const useFoods = function () {
const deleteTargetId = ref(0);
const validForm = ref(true);
const workingFoodData = reactive({
id: 0,
const workingFoodData = reactive<IngredientFood>({
id: "",
name: "",
description: "",
labelId: "",
labelId: undefined,
});
const actions = {
@ -80,16 +80,16 @@ export const useFoods = function () {
}
},
resetWorking() {
workingFoodData.id = 0;
workingFoodData.id = "";
workingFoodData.name = "";
workingFoodData.description = "";
workingFoodData.labelId = "";
workingFoodData.labelId = undefined;
},
setWorking(item: IngredientFood) {
workingFoodData.id = item.id;
workingFoodData.name = item.name;
workingFoodData.description = item.description || "";
workingFoodData.labelId = item.labelId || "";
workingFoodData.labelId = item.labelId;
},
flushStore() {
foodStore = null;

View file

@ -1,9 +1,7 @@
import { Ref } from "@nuxtjs/composition-api";
// import { useStaticRoutes } from "../api";
import { Recipe } from "~/types/api-types/recipe";
export const useRecipeMeta = (recipe: Ref<Recipe | null>) => {
// const { recipeImage } = useStaticRoutes();
return () => {
const imageURL = "";
return {

View file

@ -2,10 +2,11 @@ import { reactive, ref, useAsync } from "@nuxtjs/composition-api";
import { useAsyncKey } from "../use-utils";
import { useUserApi } from "~/composables/api";
import { VForm } from "~/types/vuetify";
import { RecipeTool } from "~/types/api-types/user";
export const useTools = function (eager = true) {
const workingToolData = reactive({
id: 0,
const workingToolData = reactive<RecipeTool>({
id: "",
name: "",
slug: "",
onHand: false,
@ -72,7 +73,7 @@ export const useTools = function (eager = true) {
reset() {
workingToolData.name = "";
workingToolData.id = 0;
workingToolData.id = "";
loading.value = false;
validForm.value = true;
},

View file

@ -1,13 +1,17 @@
import { Ref, ref, useAsync } from "@nuxtjs/composition-api";
import { useUserApi } from "../api";
import { useAsyncKey } from "../use-utils";
import { CategoriesAPI, Category } from "~/api/class-interfaces/categories";
import { Tag, TagsAPI } from "~/api/class-interfaces/tags";
import { CategoriesAPI } from "~/api/class-interfaces/organizer-categories";
import { TagsAPI } from "~/api/class-interfaces/organizer-tags";
import { RecipeTag, RecipeCategory } from "~/types/api-types/recipe";
export const allCategories = ref<Category[] | null>([]);
export const allTags = ref<Tag[] | null>([]);
export const allCategories = ref<RecipeCategory[] | null>([]);
export const allTags = ref<RecipeTag[] | null>([]);
function baseTagsCategories(reference: Ref<Category[] | null> | Ref<Tag[] | null>, api: TagsAPI | CategoriesAPI) {
function baseTagsCategories(
reference: Ref<RecipeCategory[] | null> | Ref<RecipeTag[] | null>,
api: TagsAPI | CategoriesAPI
) {
function useAsyncGetAll() {
useAsync(async () => {
await refreshItems();