feat(dish): add dish management and public view
Add database schema, permissions, and API endpoints for dishes Implement frontend views and admin management for dish data
This commit is contained in:
@@ -35,12 +35,15 @@ CREATE TABLE IF NOT EXISTS entity_translations (
|
||||
'habitats',
|
||||
'daily-checklist-items',
|
||||
'life-tags',
|
||||
'game-versions'
|
||||
'game-versions',
|
||||
'dish-categories',
|
||||
'dish-flavors',
|
||||
'dishes'
|
||||
)
|
||||
),
|
||||
entity_id integer NOT NULL,
|
||||
locale text NOT NULL REFERENCES languages(code) ON DELETE CASCADE,
|
||||
field_name text NOT NULL CHECK (field_name IN ('name', 'title', 'details', 'genus')),
|
||||
field_name text NOT NULL CHECK (field_name IN ('name', 'title', 'details', 'genus', 'effect', 'mosslaxEffect')),
|
||||
value text NOT NULL,
|
||||
PRIMARY KEY (entity_type, entity_id, locale, field_name)
|
||||
);
|
||||
@@ -68,10 +71,21 @@ ALTER TABLE entity_translations
|
||||
'habitats',
|
||||
'daily-checklist-items',
|
||||
'life-tags',
|
||||
'game-versions'
|
||||
'game-versions',
|
||||
'dish-categories',
|
||||
'dish-flavors',
|
||||
'dishes'
|
||||
)
|
||||
);
|
||||
|
||||
ALTER TABLE entity_translations
|
||||
DROP CONSTRAINT IF EXISTS entity_translations_field_name_check;
|
||||
|
||||
ALTER TABLE entity_translations
|
||||
ADD CONSTRAINT entity_translations_field_name_check CHECK (
|
||||
field_name IN ('name', 'title', 'details', 'genus', 'effect', 'mosslaxEffect')
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
email text NOT NULL UNIQUE,
|
||||
@@ -291,6 +305,10 @@ VALUES
|
||||
('recipes.update', 'Update recipes', 'Edit recipe records.', 'Recipes', true),
|
||||
('recipes.delete', 'Delete recipes', 'Delete recipe records.', 'Recipes', true),
|
||||
('recipes.order', 'Order recipes', 'Reorder recipe records.', 'Recipes', true),
|
||||
('dish.create', 'Create Dish records', 'Create Dish categories and dish records.', 'Dish', true),
|
||||
('dish.update', 'Update Dish records', 'Edit Dish categories and dish records.', 'Dish', true),
|
||||
('dish.delete', 'Delete Dish records', 'Delete Dish categories and dish records.', 'Dish', true),
|
||||
('dish.order', 'Order Dish records', 'Reorder Dish categories and dish records.', 'Dish', true),
|
||||
('life.posts.create', 'Create Life posts', 'Create Life posts.', 'Life', true),
|
||||
('life.posts.update', 'Update own Life posts', 'Edit own Life posts.', 'Life', true),
|
||||
('life.posts.delete', 'Delete own Life posts', 'Delete own Life posts.', 'Life', true),
|
||||
@@ -385,6 +403,10 @@ JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'recipes.update',
|
||||
'recipes.delete',
|
||||
'recipes.order',
|
||||
'dish.create',
|
||||
'dish.update',
|
||||
'dish.delete',
|
||||
'dish.order',
|
||||
'life.posts.create',
|
||||
'life.posts.update',
|
||||
'life.posts.delete',
|
||||
@@ -459,6 +481,9 @@ JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'recipes.create',
|
||||
'recipes.update',
|
||||
'recipes.order',
|
||||
'dish.create',
|
||||
'dish.update',
|
||||
'dish.order',
|
||||
'life.posts.create',
|
||||
'life.posts.update',
|
||||
'life.posts.delete',
|
||||
@@ -505,6 +530,29 @@ JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
WHERE r.key = 'editor'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r
|
||||
JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'dish.create',
|
||||
'dish.update',
|
||||
'dish.delete',
|
||||
'dish.order'
|
||||
])
|
||||
WHERE r.key = 'admin'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r
|
||||
JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'dish.create',
|
||||
'dish.update',
|
||||
'dish.order'
|
||||
])
|
||||
WHERE r.key = 'editor'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r
|
||||
@@ -1024,6 +1072,112 @@ CREATE TABLE IF NOT EXISTS recipe_materials (
|
||||
PRIMARY KEY (recipe_id, item_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dish_categories (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
cookware_item_id integer NOT NULL REFERENCES items(id),
|
||||
main_material_item_id integer NOT NULL REFERENCES items(id),
|
||||
total_material_quantity integer NOT NULL DEFAULT 2 CHECK (total_material_quantity >= 2),
|
||||
effect text NOT NULL DEFAULT '',
|
||||
sort_order integer NOT NULL DEFAULT 0 CHECK (sort_order >= 0),
|
||||
created_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
updated_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
ADD COLUMN IF NOT EXISTS main_material_item_id integer REFERENCES items(id);
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
ADD COLUMN IF NOT EXISTS total_material_quantity integer NOT NULL DEFAULT 2;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.dishes') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'dishes'
|
||||
AND column_name = 'main_material_item_id'
|
||||
)
|
||||
THEN
|
||||
EXECUTE '
|
||||
UPDATE dish_categories dc
|
||||
SET main_material_item_id = source.main_material_item_id
|
||||
FROM (
|
||||
SELECT DISTINCT ON (category_id) category_id, main_material_item_id
|
||||
FROM dishes
|
||||
WHERE main_material_item_id IS NOT NULL
|
||||
ORDER BY category_id, sort_order, id
|
||||
) AS source
|
||||
WHERE dc.id = source.category_id
|
||||
AND dc.main_material_item_id IS NULL
|
||||
';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
UPDATE dish_categories
|
||||
SET main_material_item_id = cookware_item_id
|
||||
WHERE main_material_item_id IS NULL;
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
ALTER COLUMN main_material_item_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
ALTER COLUMN total_material_quantity SET DEFAULT 2;
|
||||
|
||||
UPDATE dish_categories
|
||||
SET total_material_quantity = 2
|
||||
WHERE total_material_quantity < 2;
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
DROP CONSTRAINT IF EXISTS dish_categories_total_material_quantity_check;
|
||||
|
||||
ALTER TABLE dish_categories
|
||||
ADD CONSTRAINT dish_categories_total_material_quantity_check CHECK (total_material_quantity >= 2);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dish_flavors (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
sort_order integer NOT NULL DEFAULT 0 CHECK (sort_order >= 0),
|
||||
created_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
updated_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dishes (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
category_id integer NOT NULL REFERENCES dish_categories(id) ON DELETE CASCADE,
|
||||
item_id integer NOT NULL UNIQUE REFERENCES items(id),
|
||||
flavor_id integer NOT NULL REFERENCES dish_flavors(id),
|
||||
secondary_material_1_item_id integer REFERENCES items(id),
|
||||
secondary_material_2_item_id integer REFERENCES items(id),
|
||||
pokemon_skill_id integer REFERENCES skills(id),
|
||||
mosslax_effect text NOT NULL DEFAULT '',
|
||||
sort_order integer NOT NULL DEFAULT 0 CHECK (sort_order >= 0),
|
||||
created_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
updated_by_user_id integer REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CHECK (
|
||||
secondary_material_1_item_id IS NULL
|
||||
OR secondary_material_2_item_id IS NULL
|
||||
OR secondary_material_1_item_id <> secondary_material_2_item_id
|
||||
)
|
||||
);
|
||||
|
||||
ALTER TABLE dishes
|
||||
ADD COLUMN IF NOT EXISTS flavor_id integer REFERENCES dish_flavors(id);
|
||||
|
||||
ALTER TABLE dishes
|
||||
ALTER COLUMN secondary_material_1_item_id DROP NOT NULL;
|
||||
|
||||
ALTER TABLE dishes
|
||||
DROP COLUMN IF EXISTS main_material_item_id;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS maps (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
@@ -1193,6 +1347,10 @@ CREATE INDEX IF NOT EXISTS items_display_order_idx ON items(is_event_item, displ
|
||||
CREATE INDEX IF NOT EXISTS ancient_artifacts_sort_order_idx ON ancient_artifacts(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS ancient_artifacts_display_order_idx ON ancient_artifacts(display_id, sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS recipes_sort_order_idx ON recipes(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS dish_categories_sort_order_idx ON dish_categories(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS dish_flavors_sort_order_idx ON dish_flavors(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS dishes_category_sort_order_idx ON dishes(category_id, sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS dishes_sort_order_idx ON dishes(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS maps_sort_order_idx ON maps(sort_order, id);
|
||||
CREATE INDEX IF NOT EXISTS habitats_sort_order_idx ON habitats(sort_order, id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user