Index: ckend/01.init.sql
===================================================================
--- backend/01.init.sql	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,681 +1,0 @@
-BEGIN;
-
-CREATE TABLE IF NOT EXISTS users (
-                                     id BIGSERIAL PRIMARY KEY,
-                                     email VARCHAR(255) NOT NULL UNIQUE,
-    password VARCHAR(255) NOT NULL,
-    phone_number VARCHAR(50) UNIQUE,
-    street VARCHAR(255),
-    city VARCHAR(255)
-    );
-
-CREATE TABLE IF NOT EXISTS employees (
-                                         user_id BIGSERIAL PRIMARY KEY,
-                                         net_salary DECIMAL(10,2),
-    gross_salary DECIMAL(10,2),
-    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS customers (
-                                         user_id BIGSERIAL PRIMARY KEY,
-                                         FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS staff_roles (
-                                           id BIGSERIAL PRIMARY KEY,
-                                           name VARCHAR(255) NOT NULL
-    );
-
-CREATE TABLE IF NOT EXISTS front_staff (
-                                           employee_id BIGSERIAL PRIMARY KEY,
-                                           tip_percent DECIMAL(10,2),
-    staff_role_id BIGINT NOT NULL,
-    FOREIGN KEY (employee_id) REFERENCES employees (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (staff_role_id) REFERENCES staff_roles (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS back_staff (
-                                          employee_id BIGSERIAL PRIMARY KEY,
-                                          staff_role_id BIGINT NOT NULL,
-                                          FOREIGN KEY (employee_id) REFERENCES employees (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (staff_role_id) REFERENCES staff_roles (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS managers (
-                                        employee_id BIGSERIAL PRIMARY KEY,
-                                        FOREIGN KEY (employee_id) REFERENCES employees (user_id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS shifts (
-                                      id BIGSERIAL PRIMARY KEY,
-                                      date DATE NOT NULL,
-                                      start_time TIME NOT NULL,
-                                      end_time TIME NOT NULL,
-                                      manager_id BIGINT NOT NULL,
-                                      FOREIGN KEY (manager_id) REFERENCES managers (employee_id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS assignments (
-                                           id BIGSERIAL PRIMARY KEY,
-                                           clock_in_time TIME,
-                                           clock_out_time TIME,
-                                           manager_id BIGINT NOT NULL,
-                                           employee_id BIGINT NOT NULL,
-                                           shift_id BIGINT NOT NULL,
-                                           FOREIGN KEY (manager_id) REFERENCES managers (employee_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (employee_id) REFERENCES employees (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (shift_id) REFERENCES shifts (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS tables (
-                                      table_number BIGSERIAL PRIMARY KEY,
-                                      seat_capacity INT NOT NULL
-);
-
-CREATE TABLE IF NOT EXISTS reservations (
-                                            id BIGSERIAL PRIMARY KEY,
-                                            user_id BIGINT NOT NULL,
-                                            creation_timestamp TIMESTAMP NOT NULL,
-                                            datetime TIMESTAMP NOT NULL,
-                                            number_of_people BIGINT NOT NULL,
-                                            stay_length DECIMAL(10,2) NULL, --hours
-    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS frontstaff_managed_reservations (
-                                                               id BIGSERIAL PRIMARY KEY,
-                                                               reservation_id BIGINT NOT NULL,
-                                                               front_staff_id BIGINT NOT NULL,
-                                                               table_number BIGINT NOT NULL,
-                                                               FOREIGN KEY (reservation_id) REFERENCES reservations (id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (front_staff_id) REFERENCES front_staff (employee_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (table_number) REFERENCES tables (table_number) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS categories (
-                                          id BIGSERIAL PRIMARY KEY,
-                                          name VARCHAR(255) NOT NULL,
-    is_available BOOLEAN NOT NULL DEFAULT TRUE
-    );
-
-CREATE TABLE IF NOT EXISTS products (
-                                        id BIGSERIAL PRIMARY KEY,
-                                        name VARCHAR(255) NOT NULL,
-    description VARCHAR(1000) NOT NULL,
-    price DECIMAL(10,2) NOT NULL,
-    category_id BIGINT NOT NULL,
-    manage_inventory BOOLEAN NOT NULL DEFAULT FALSE,
-    tax_class VARCHAR(4) NOT NULL,
-    FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS inventories (
-                                           product_id BIGSERIAL PRIMARY KEY,
-                                           quantity INT NOT NULL,
-                                           restock_level INT NULL,
-                                           FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS orders (
-                                      id BIGSERIAL PRIMARY KEY,
-                                      status VARCHAR(255) NOT NULL DEFAULT 'PENDING',
-    datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    employee_id BIGINT DEFAULT NULL,
-    FOREIGN KEY (employee_id) REFERENCES employees(user_id) ON DELETE SET NULL ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS order_items (
-                                           id BIGSERIAL PRIMARY KEY,
-                                           order_id BIGINT NOT NULL,
-                                           product_id BIGINT NOT NULL,
-                                           is_processed BOOLEAN NOT NULL DEFAULT FALSE,
-                                           quantity INT NOT NULL,
-                                           price DECIMAL(10,2) NOT NULL,
-    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS tab_orders (
-                                          order_id BIGSERIAL PRIMARY KEY,
-                                          table_number BIGINT NOT NULL,
-                                          FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (table_number) REFERENCES tables (table_number) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS online_orders (
-                                             order_id BIGSERIAL PRIMARY KEY,
-                                             delivery_address VARCHAR(255) NOT NULL,
-    customer_id BIGINT NOT NULL,
-    FOREIGN KEY (customer_id) REFERENCES customers (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
-CREATE TABLE IF NOT EXISTS payments (
-                                        id BIGSERIAL PRIMARY KEY,
-                                        order_id BIGINT NOT NULL,
-                                        amount DECIMAL(10,2) NOT NULL,
-    payment_type VARCHAR(32) NOT NULL,
-    tip_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
-    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE ON UPDATE CASCADE
-    );
-
----
--- Assertions
-
-ALTER TABLE employees
-    ADD CONSTRAINT employees_net_salary_nonneg CHECK (net_salary IS NULL OR net_salary >= 0),
-    ADD CONSTRAINT employees_gross_salary_nonneg CHECK (gross_salary IS NULL OR gross_salary >= 0);
-
-ALTER TABLE inventories
-    ADD CONSTRAINT inventories_qty_nonneg CHECK (quantity >= 0),
-    ADD CONSTRAINT inventories_restock_nonneg CHECK (restock_level IS NULL OR restock_level >= 0);
-
-ALTER TABLE products
-    ADD CONSTRAINT products_price_nonneg CHECK (price >= 0);
-
-ALTER TABLE order_items
-    ADD CONSTRAINT order_items_qty_pos CHECK (quantity > 0),
-    ADD CONSTRAINT order_items_price_nonneg CHECK (price >= 0);
-
-ALTER TABLE payments
-    ADD CONSTRAINT payments_amount_nonneg CHECK (amount >= 0),
-    ADD CONSTRAINT payments_tip_nonneg CHECK (tip_amount >= 0);
-
-ALTER TABLE tables
-    ADD CONSTRAINT tables_capacity_pos CHECK (seat_capacity > 0);
-
-ALTER TABLE reservations
-    ADD CONSTRAINT reservations_people_pos CHECK (number_of_people > 0);
-
-ALTER TABLE front_staff
-    ADD CONSTRAINT front_staff_tip_pct CHECK (tip_percent IS NULL OR (tip_percent >= 0 AND tip_percent <= 100));
-
----
--- Functions & Triggers
-
-CREATE OR REPLACE FUNCTION enforce_no_double_booking()
-RETURNS trigger AS $$
-DECLARE
-new_span tsrange;
-    conflict_exists boolean;
-BEGIN
-SELECT tsrange(
-               r.datetime,
-               r.datetime + (COALESCE(r.stay_length, 2) * INTERVAL '1 hour'),
-               '[)'
-           ) INTO new_span
-FROM reservations r
-WHERE r.id = NEW.reservation_id;
-
-IF new_span IS NULL THEN
-        RAISE EXCEPTION 'Reservation % not found or invalid', NEW.reservation_id;
-END IF;
-
-SELECT EXISTS (
-    SELECT 1
-    FROM frontstaff_managed_reservations fmr
-             JOIN reservations r2 ON r2.id = fmr.reservation_id
-    WHERE fmr.table_number = NEW.table_number
-      AND (NEW.id IS NULL OR fmr.id <> NEW.id)
-      AND tsrange(
-            r2.datetime,
-            r2.datetime + (COALESCE(r2.stay_length, 2) * INTERVAL '1 hour'),
-            '[)'
-        ) && new_span
-) INTO conflict_exists;
-
-IF conflict_exists THEN
-        RAISE EXCEPTION 'Double booking prevented: table % has overlapping reservations', NEW.table_number;
-END IF;
-
-RETURN NEW;
-END;
-$$ LANGUAGE plpgsql;
-
-DROP TRIGGER IF EXISTS trg_no_double_booking_ins ON frontstaff_managed_reservations;
-CREATE CONSTRAINT TRIGGER trg_no_double_booking_ins
-AFTER INSERT ON frontstaff_managed_reservations
-DEFERRABLE INITIALLY DEFERRED
-FOR EACH ROW EXECUTE FUNCTION enforce_no_double_booking();
-
-DROP TRIGGER IF EXISTS trg_no_double_booking_upd ON frontstaff_managed_reservations;
-CREATE CONSTRAINT TRIGGER trg_no_double_booking_upd
-AFTER UPDATE ON frontstaff_managed_reservations
-                 DEFERRABLE INITIALLY DEFERRED
-                 FOR EACH ROW EXECUTE FUNCTION enforce_no_double_booking();
-
-CREATE INDEX IF NOT EXISTS fmr_table_idx ON frontstaff_managed_reservations (table_number);
-CREATE INDEX IF NOT EXISTS reservations_span_expr_gist
-    ON reservations USING gist (
-    tsrange(
-    datetime,
-    datetime + (COALESCE(stay_length, 2) * INTERVAL '1 hour'),
-    '[)'
-    )
-    );
-CREATE INDEX IF NOT EXISTS idx_payments_order ON payments(order_id);
-CREATE INDEX IF NOT EXISTS idx_payments_created_at ON payments(created_at);
-
-CREATE OR REPLACE FUNCTION fmr_capacity_guard() RETURNS trigger AS $$
-DECLARE
-cap int;
-    party bigint;
-BEGIN
-SELECT seat_capacity INTO cap FROM tables WHERE table_number = NEW.table_number;
-SELECT number_of_people INTO party FROM reservations WHERE id = NEW.reservation_id;
-
-IF cap IS NULL OR party IS NULL THEN
-        RAISE EXCEPTION 'Invalid reservation % or table %', NEW.reservation_id, NEW.table_number;
-END IF;
-
-    IF party > cap THEN
-        RAISE EXCEPTION 'Party size % exceeds capacity % for table %',
-            party, cap, NEW.table_number;
-END IF;
-
-RETURN NEW;
-END;
-$$ LANGUAGE plpgsql;
-
-DROP TRIGGER IF EXISTS trg_fmr_capacity_ins ON frontstaff_managed_reservations;
-CREATE TRIGGER trg_fmr_capacity_ins
-    BEFORE INSERT ON frontstaff_managed_reservations
-    FOR EACH ROW EXECUTE FUNCTION fmr_capacity_guard();
-
-DROP TRIGGER IF EXISTS trg_fmr_capacity_upd ON frontstaff_managed_reservations;
-CREATE TRIGGER trg_fmr_capacity_upd
-    BEFORE UPDATE ON frontstaff_managed_reservations
-    FOR EACH ROW EXECUTE FUNCTION fmr_capacity_guard();
-
-CREATE OR REPLACE FUNCTION payments_mark_order_paid() RETURNS trigger AS $$
-BEGIN
-UPDATE orders
-SET status = 'PAID'
-WHERE id = NEW.order_id;
-RETURN NEW;
-END;
-$$ LANGUAGE plpgsql;
-
-DROP TRIGGER IF EXISTS trg_payments_mark_order_paid ON payments;
-CREATE TRIGGER trg_payments_mark_order_paid
-    AFTER INSERT ON payments
-    FOR EACH ROW EXECUTE FUNCTION payments_mark_order_paid();
-
-
-CREATE MATERIALIZED VIEW IF NOT EXISTS mv_payments_daily_channel AS
-WITH orders_channel AS (
-    SELECT
-        o.id AS order_id,
-        CASE
-            WHEN EXISTS (SELECT 1 FROM tab_orders t WHERE t.order_id = o.id) THEN 'TAB'
-            WHEN EXISTS (SELECT 1 FROM online_orders oo WHERE oo.order_id = o.id) THEN 'ONLINE'
-            ELSE 'UNKNOWN'
-        END AS channel
-    FROM orders o
-)
-SELECT
-    (date_trunc('day', p.created_at))::date AS day,
-    oc.channel,
-    COUNT(DISTINCT p.order_id) AS paid_orders_cnt,
-    SUM(p.amount)::numeric(14,2) AS revenue,
-    SUM(p.tip_amount)::numeric(14,2) AS tip_total
-FROM payments p
-    JOIN orders_channel oc ON oc.order_id = p.order_id
-GROUP BY (date_trunc('day', p.created_at))::date, oc.channel;
-
-CREATE UNIQUE INDEX IF NOT EXISTS ux_mv_payments_daily_channel
-    ON mv_payments_daily_channel (day, channel);
-
----
--- DML
-
-INSERT INTO users(id, email, password, phone_number, street, city)
-VALUES
-    (1, 'test@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070003005', 'Mladinska 3', 'Strumica'),
-    (2, 'test2@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070001002', 'Marsal Tito 10', 'Strumica'),
-    (3, 'test3@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070003003', 'Mladinska 5', 'Strumica'),
-    (4, 'test4@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070004004', 'Marsal Tito 11', 'Strumica'),
-    (5, 'test5@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070005005', 'Mladinska 12', 'Strumica');
-
-INSERT INTO employees(user_id, net_salary, gross_salary)
-VALUES
-    (1, 30000, 40000),
-    (3, 50000, 62000),
-    (4, 35000, 46000),
-    (5, 28000, 37000);
-
-INSERT INTO managers(employee_id)
-VALUES
-    (3);
-
-INSERT INTO staff_roles(id, name)
-VALUES
-    (1, 'Server'),
-    (2, 'Chef'),
-    (3, 'Bartender'),
-    (4, 'Hostess');
-
-INSERT INTO front_staff(employee_id, tip_percent, staff_role_id)
-VALUES
-    (1, .4, 1),
-    (5, 0.1, 4);
-
-INSERT INTO back_staff(employee_id, staff_role_id)
-VALUES
-    (4, 2);
-
-INSERT INTO customers(user_id)
-VALUES
-    (2);
-
-INSERT INTO shifts (id, date, start_time, end_time, manager_id)
-VALUES
-    (1, current_date, '09:00:00', '17:00:00', 3);
-
-INSERT INTO assignments(id, clock_in_time, clock_out_time, manager_id, employee_id, shift_id)
-VALUES
-    (1, NULL, NULL, 3, 1, 1);
-
-INSERT INTO tables(table_number, seat_capacity)
-VALUES
-    (1, 4),
-    (2, 8);
-
-INSERT INTO reservations(id, user_id, creation_timestamp, datetime, stay_length, number_of_people)
-VALUES
-    (1, 2, now(), now(), NULL, 4);
-
-INSERT INTO frontstaff_managed_reservations(id, reservation_id, front_staff_id, table_number)
-VALUES
-    (1, 1, 5, 1);
-
-INSERT INTO categories(id, name)
-VALUES
-    (1, 'Drinks'),
-    (2, 'Appetizers'),
-    (3, 'Entrees');
-
-INSERT INTO products(id, name, description, price, category_id, manage_inventory, tax_class)
-VALUES
-    (1, 'Coca Cola', 'A classic carbonated soft drink.', 100, 1, TRUE, 'A'),
-    (2, 'Pomfrit so sirenje', 'Crispy french fries topped with melted cheese.', 250, 2, FALSE, 'A');
-
-INSERT INTO inventories(product_id, quantity)
-VALUES
-    (1, 100);
-
-INSERT INTO orders(id, status, datetime, employee_id)
-VALUES
-    (1, 'PENDING', '2025-01-05 10:00:00', 1),
-    (2, 'ACCEPTED', '2025-01-05 10:00:00', 1),
-    (3, 'CONFIRMED', '2025-01-05 11:00:00', NULL);
-
-INSERT INTO order_items (id, order_id, product_id, is_processed, quantity, price)
-SELECT 1, 1, 1, TRUE, 3, price FROM products WHERE id = 1
-UNION ALL
-SELECT 2, 1, 2, FALSE, 1, price FROM products WHERE id = 2
-UNION ALL
-SELECT 3, 3, 2, FALSE, 2, price FROM products WHERE id = 2
-UNION ALL
-SELECT 4, 3, 1, FALSE, 2, price FROM products WHERE id = 1;
-
-INSERT INTO tab_orders(order_id, table_number)
-VALUES
-    (1, 1);
-
-INSERT INTO online_orders(order_id, delivery_address, customer_id)
-VALUES
-    (3, 'Leninova 5', 2);
-
-INSERT INTO payments(id, order_id, amount, payment_type, tip_amount)
-VALUES
-    (1, 3, 700, 'cash', 10);
-
-REFRESH MATERIALIZED VIEW mv_payments_daily_channel;
-
----
--- Analytics
-
--- ANALYTIC: Server performance & revenue ranking (last 3 months)
-WITH server_metrics AS (
-    SELECT
-        fs.employee_id,
-        u.email as server_email,
-        COUNT(DISTINCT a.id) as total_assignments,
-        COUNT(DISTINCT o.id) as orders_processed,
-        COALESCE(SUM(oi.quantity * oi.price), 0) as total_revenue_generated
-    FROM front_staff fs
-             JOIN employees e ON fs.employee_id = e.user_id
-             JOIN users u ON e.user_id = u.id
-             JOIN staff_roles sr ON fs.staff_role_id = sr.id
-             LEFT JOIN assignments a ON fs.employee_id = a.employee_id
-             LEFT JOIN shifts s ON a.shift_id = s.id
-             LEFT JOIN orders o ON o.employee_id = fs.employee_id
-        AND o.datetime >= CURRENT_DATE - INTERVAL '3 months'
-    LEFT JOIN order_items oi ON o.id = oi.order_id
-WHERE LOWER(sr.name) = 'server'
-GROUP BY fs.employee_id, u.email, u.phone_number,
-    e.net_salary, e.gross_salary, fs.tip_percent, sr.name
-    ),
-    performance_ranking AS (
-SELECT *,
-    RANK() OVER (ORDER BY total_revenue_generated DESC) as revenue_rank,
-    RANK() OVER (ORDER BY orders_processed DESC) as orders_rank,
-    CASE
-    WHEN total_assignments > 0
-    THEN (orders_processed::float / total_assignments)
-    ELSE 0
-    END as orders_per_assignment,
-    CASE
-    WHEN orders_processed > 0
-    THEN total_revenue_generated / orders_processed
-    ELSE 0
-    END as avg_revenue_per_order
-FROM server_metrics
-    )
-SELECT
-    server_email,
-    total_assignments,
-    orders_processed,
-    total_revenue_generated,
-    revenue_rank,
-    orders_rank,
-    ROUND(orders_per_assignment::numeric, 2) as avg_orders_per_shift,
-    ROUND(avg_revenue_per_order::numeric, 2) as avg_order_value
-FROM performance_ranking
-ORDER BY total_revenue_generated DESC, orders_processed DESC;
-
--- ANALYTIC: Monthly revenue vs labor cost (% of revenue)
-WITH monthly_revenue AS (
-    SELECT
-        DATE_TRUNC('month', o.datetime) as operation_month,
-        SUM(oi.quantity * oi.price) as revenue
-    FROM orders o
-             JOIN order_items oi ON o.id = oi.order_id
-    GROUP BY DATE_TRUNC('month', o.datetime)
-),
-     monthly_labor_cost AS (
-         SELECT
-             monthly_assignments.operation_month,
-             SUM(e.gross_salary) as labor_cost
-         FROM (
-                  SELECT DISTINCT
-                      DATE_TRUNC('month', s.date) as operation_month,
-                      a.employee_id
-                  FROM shifts s
-                           JOIN assignments a ON s.id = a.shift_id
-              ) as monthly_assignments
-                  JOIN employees e ON monthly_assignments.employee_id = e.user_id
-         GROUP BY monthly_assignments.operation_month
-     )
-SELECT
-    TO_CHAR(COALESCE(mr.operation_month, mlc.operation_month), 'YYYY-MM') as period,
-    ROUND(COALESCE(mr.revenue, 0)::numeric, 2) as total_revenue,
-    ROUND(COALESCE(mlc.labor_cost, 0)::numeric, 2) as total_labor_cost,
-    ROUND(
-            CASE
-                WHEN COALESCE(mr.revenue, 0) > 0
-                    THEN (COALESCE(mlc.labor_cost, 0) / mr.revenue * 100)
-                ELSE 0
-                END::numeric, 2
-        ) as labor_as_percent_of_revenue
-FROM monthly_revenue mr
-         FULL OUTER JOIN monthly_labor_cost mlc ON mr.operation_month = mlc.operation_month
-ORDER BY period DESC;
-
--- ANALYTIC: Daily operations summary (30 days) with conversion & revenue thresholds
-SELECT
-    dates.operation_date,
-    COUNT(DISTINCT r.id) as total_reservations,
-    COUNT(DISTINCT o.id) as total_orders,
-    COUNT(DISTINCT r.user_id) as unique_customers,
-    COUNT(DISTINCT a.employee_id) as active_employees,
-    COALESCE(SUM(oi.quantity * oi.price), 0) as daily_revenue
-FROM generate_series(
-                         CURRENT_DATE - INTERVAL '30 days',
-                         CURRENT_DATE,
-                         '1 day'::interval
-         ) dates(operation_date)
-         LEFT JOIN reservations r ON DATE(r.datetime) = dates.operation_date
-    LEFT JOIN orders o ON DATE(o.datetime) = dates.operation_date
-    LEFT JOIN order_items oi ON o.id = oi.order_id
-    LEFT JOIN shifts s ON DATE(s.date) = dates.operation_date
-    LEFT JOIN assignments a ON s.id = a.shift_id
-GROUP BY dates.operation_date
-ORDER BY dates.operation_date DESC;
-
--- ANALYTIC: Top 10 products by revenue (last 90 days) + revenue share
-SELECT
-    p.id as product_id,
-    p.name as product_name,
-    c.name as category_name,
-    SUM(oi.quantity) as total_quantity_sold,
-    SUM(oi.quantity * oi.price) as total_revenue,
-    ROUND(100.0 * SUM(oi.quantity * oi.price) / SUM(SUM(oi.quantity * oi.price)) OVER (), 2) as revenue_share_percent
-FROM products p
-         JOIN categories c ON p.category_id = c.id
-         JOIN order_items oi ON p.id = oi.product_id
-         JOIN orders o ON o.id = oi.order_id
-WHERE o.datetime >= CURRENT_DATE - INTERVAL '90 days'
-GROUP BY p.id, p.name, c.name
-ORDER BY total_revenue DESC
-    LIMIT 10;
-
--- ANALYTIC: Revenue by shift period (dynamic monthly view)
-CREATE OR REPLACE VIEW v_revenue_by_shift_period AS
-WITH distinct_shift_periods AS (
-    SELECT DISTINCT
-        start_time::time AS start_t,
-        end_time::time AS end_t
-    FROM shifts
-)
-SELECT
-    TO_CHAR(o.datetime, 'YYYY-MM') AS period,
-    dsp.start_t::text || '-' || dsp.end_t::text AS shift_period,
-        SUM(oi.price * oi.quantity) AS total_revenue
-FROM
-    orders o
-        JOIN
-    order_items oi ON o.id = oi.order_id
-        JOIN
-    distinct_shift_periods dsp ON o.datetime::time >= dsp.start_t AND o.datetime::time < dsp.end_t
-GROUP BY
-    period,
-    shift_period
-ORDER BY
-    period DESC,
-    shift_period ASC;
-
--- ANALYTIC: Revenue split (Online vs Tab) for a date range (by order date)
-DROP FUNCTION IF EXISTS get_revenue_split(date, date);
-
-CREATE OR REPLACE FUNCTION get_revenue_split(p_start_date DATE, p_end_date DATE)
-RETURNS TABLE(order_type TEXT, total_revenue NUMERIC(14,2)) AS $$
-BEGIN
-RETURN QUERY
-SELECT 'Online Orders'::text AS order_type,
-        COALESCE(SUM(p.amount), 0)::numeric(14,2) AS total_revenue
-FROM orders o
-         JOIN payments p ON o.id = p.order_id
-         JOIN online_orders oo ON o.id = oo.order_id
-WHERE o.datetime::date BETWEEN p_start_date AND p_end_date
-UNION ALL
-SELECT 'Tab Orders'::text AS order_type,
-        COALESCE(SUM(p.amount), 0)::numeric(14,2) AS total_revenue
-FROM orders o
-         JOIN payments p ON o.id = p.order_id
-         JOIN tab_orders tord ON o.id = tord.order_id
-WHERE o.datetime::date BETWEEN p_start_date AND p_end_date;
-END;
-$$ LANGUAGE plpgsql;
-
--- ANALYTIC: Managers' shifts above monthly average revenue (current calendar year)
-WITH manager_worked_shifts AS (
-    SELECT DISTINCT
-        s.id AS shift_id,
-        s.date,
-        s.start_time,
-        s.end_time,
-        a.employee_id AS manager_id
-    FROM assignments a
-             JOIN shifts s ON s.id = a.shift_id
-             JOIN managers m ON m.employee_id = a.employee_id
-    WHERE s.date >= date_trunc('year', CURRENT_DATE)::date
-    AND s.date < (date_trunc('year', CURRENT_DATE) + INTERVAL '1 year')::date
-    ),
-    shift_revenue AS (
-SELECT
-    mws.shift_id,
-    date_trunc('month', mws.date)::date AS month_start,
-    mws.date AS shift_date,
-    mws.start_time,
-    mws.end_time,
-    mws.manager_id,
-    COALESCE(SUM(oi.quantity * oi.price), 0)::numeric(14,2) AS shift_revenue
-FROM manager_worked_shifts mws
-    LEFT JOIN orders o
-ON o.datetime::date = mws.date
-    AND o.datetime::time >= mws.start_time
-    AND o.datetime::time < mws.end_time
-    LEFT JOIN order_items oi ON oi.order_id = o.id
-GROUP BY
-    mws.shift_id, month_start, mws.date, mws.start_time, mws.end_time, mws.manager_id
-    ),
-    monthly_avg AS (
-SELECT month_start, AVG(shift_revenue)::numeric(14,2) AS avg_revenue_per_shift
-FROM shift_revenue
-GROUP BY month_start
-    )
-SELECT
-    to_char(sr.month_start, 'YYYY-MM') AS period,
-    sr.shift_id,
-    sr.shift_date,
-    sr.start_time AS shift_start_time,
-    sr.end_time AS shift_end_time,
-    u.email AS manager_email,
-    sr.shift_revenue,
-    ma.avg_revenue_per_shift,
-    (sr.shift_revenue - ma.avg_revenue_per_shift)::numeric(14,2) AS above_by
-FROM shift_revenue sr
-         JOIN monthly_avg ma ON ma.month_start = sr.month_start
-         JOIN managers m ON m.employee_id = sr.manager_id
-         JOIN employees e ON e.user_id = m.employee_id
-         JOIN users u ON u.id = e.user_id
-WHERE sr.shift_revenue > ma.avg_revenue_per_shift
-ORDER BY period DESC, sr.shift_revenue DESC, sr.shift_date DESC;
-
-SELECT setval('public.users_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.users) + 1, false);
-SELECT setval('public.staff_roles_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.staff_roles) + 1, false);
-SELECT setval('public.shifts_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.shifts) + 1, false);
-SELECT setval('public.assignments_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.assignments) + 1, false);
-SELECT setval('public.reservations_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.reservations) + 1, false);
-SELECT setval('public.frontstaff_managed_reservations_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.frontstaff_managed_reservations) + 1, false);
-SELECT setval('public.categories_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.categories) + 1, false);
-SELECT setval('public.products_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.products) + 1, false);
-SELECT setval('public.orders_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.orders) + 1, false);
-SELECT setval('public.order_items_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.order_items) + 1, false);
-SELECT setval('public.payments_id_seq', (SELECT COALESCE(MAX(id), 0) FROM public.payments) + 1, false);
-
-COMMIT;
Index: ckend/docker-compose.yml
===================================================================
--- backend/docker-compose.yml	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,18 +1,0 @@
-version: '3.8'
-
-services:
-  db:
-    image: postgres:15.5
-    restart: always
-    environment:
-      POSTGRES_USER: springuser
-      POSTGRES_PASSWORD: springpassword
-      POSTGRES_DB: spring_boot_db
-    volumes:
-      - db_data:/var/lib/postgresql/data
-      - ./01.init.sql:/docker-entrypoint-initdb.d/init.sql
-    ports:
-      - "5435:5432"
-
-volumes:
-  db_data:
Index: ckend/mvnw
===================================================================
--- backend/mvnw	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,259 +1,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Optional ENV vars
-# -----------------
-#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
-#   MVNW_REPOURL - repo url base for downloading maven distribution
-#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
-# ----------------------------------------------------------------------------
-
-set -euf
-[ "${MVNW_VERBOSE-}" != debug ] || set -x
-
-# OS specific support.
-native_path() { printf %s\\n "$1"; }
-case "$(uname)" in
-CYGWIN* | MINGW*)
-  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
-  native_path() { cygpath --path --windows "$1"; }
-  ;;
-esac
-
-# set JAVACMD and JAVACCMD
-set_java_home() {
-  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
-  if [ -n "${JAVA_HOME-}" ]; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
-      # IBM's JDK on AIX uses strange locations for the executables
-      JAVACMD="$JAVA_HOME/jre/sh/java"
-      JAVACCMD="$JAVA_HOME/jre/sh/javac"
-    else
-      JAVACMD="$JAVA_HOME/bin/java"
-      JAVACCMD="$JAVA_HOME/bin/javac"
-
-      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
-        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
-        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
-        return 1
-      fi
-    fi
-  else
-    JAVACMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v java
-    )" || :
-    JAVACCMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v javac
-    )" || :
-
-    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
-      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
-      return 1
-    fi
-  fi
-}
-
-# hash string like Java String::hashCode
-hash_string() {
-  str="${1:-}" h=0
-  while [ -n "$str" ]; do
-    char="${str%"${str#?}"}"
-    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
-    str="${str#?}"
-  done
-  printf %x\\n $h
-}
-
-verbose() { :; }
-[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
-
-die() {
-  printf %s\\n "$1" >&2
-  exit 1
-}
-
-trim() {
-  # MWRAPPER-139:
-  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
-  #   Needed for removing poorly interpreted newline sequences when running in more
-  #   exotic environments such as mingw bash on Windows.
-  printf "%s" "${1}" | tr -d '[:space:]'
-}
-
-# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
-while IFS="=" read -r key value; do
-  case "${key-}" in
-  distributionUrl) distributionUrl=$(trim "${value-}") ;;
-  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
-  esac
-done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-
-case "${distributionUrl##*/}" in
-maven-mvnd-*bin.*)
-  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
-  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
-  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
-  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
-  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
-  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
-  *)
-    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
-    distributionPlatform=linux-amd64
-    ;;
-  esac
-  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
-  ;;
-maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
-*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
-esac
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
-distributionUrlName="${distributionUrl##*/}"
-distributionUrlNameMain="${distributionUrlName%.*}"
-distributionUrlNameMain="${distributionUrlNameMain%-bin}"
-MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
-MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
-
-exec_maven() {
-  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
-  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
-}
-
-if [ -d "$MAVEN_HOME" ]; then
-  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  exec_maven "$@"
-fi
-
-case "${distributionUrl-}" in
-*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
-*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
-esac
-
-# prepare tmp dir
-if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
-  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
-  trap clean HUP INT TERM EXIT
-else
-  die "cannot create temp dir"
-fi
-
-mkdir -p -- "${MAVEN_HOME%/*}"
-
-# Download and Install Apache Maven
-verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-verbose "Downloading from: $distributionUrl"
-verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-# select .zip or .tar.gz
-if ! command -v unzip >/dev/null; then
-  distributionUrl="${distributionUrl%.zip}.tar.gz"
-  distributionUrlName="${distributionUrl##*/}"
-fi
-
-# verbose opt
-__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
-[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-
-# normalize http auth
-case "${MVNW_PASSWORD:+has-password}" in
-'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-esac
-
-if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
-  verbose "Found wget ... using wget"
-  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
-elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
-  verbose "Found curl ... using curl"
-  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
-elif set_java_home; then
-  verbose "Falling back to use Java to download"
-  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
-  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
-  cat >"$javaSource" <<-END
-	public class Downloader extends java.net.Authenticator
-	{
-	  protected java.net.PasswordAuthentication getPasswordAuthentication()
-	  {
-	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
-	  }
-	  public static void main( String[] args ) throws Exception
-	  {
-	    setDefault( new Downloader() );
-	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
-	  }
-	}
-	END
-  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
-  verbose " - Compiling Downloader.java ..."
-  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
-  verbose " - Running Downloader.java ..."
-  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
-fi
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-if [ -n "${distributionSha256Sum-}" ]; then
-  distributionSha256Result=false
-  if [ "$MVN_CMD" = mvnd.sh ]; then
-    echo "Checksum validation is not supported for maven-mvnd." >&2
-    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  elif command -v sha256sum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  elif command -v shasum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  else
-    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
-    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  fi
-  if [ $distributionSha256Result = false ]; then
-    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
-    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
-    exit 1
-  fi
-fi
-
-# unzip and move
-if command -v unzip >/dev/null; then
-  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
-else
-  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
-fi
-printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
-mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-
-clean || :
-exec_maven "$@"
Index: ckend/mvnw.cmd
===================================================================
--- backend/mvnw.cmd	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,149 +1,0 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements.  See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership.  The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License.  You may obtain a copy of the License at
-@REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied.  See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM   MVNW_REPOURL - repo url base for downloading maven distribution
-@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
-  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
-  $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
-  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
-  "maven-mvnd-*" {
-    $USE_MVND = $true
-    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
-    $MVN_CMD = "mvnd.cmd"
-    break
-  }
-  default {
-    $USE_MVND = $false
-    $MVN_CMD = $script -replace '^mvnw','mvn'
-    break
-  }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-if ($env:MVNW_REPOURL) {
-  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
-  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
-  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
-  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-  exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
-  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
-  if ($TMP_DOWNLOAD_DIR.Exists) {
-    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-  }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
-  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
-  if ($USE_MVND) {
-    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
-  }
-  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
-  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
-    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
-  }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
-  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
-  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
-    Write-Error "fail to move MAVEN_HOME"
-  }
-} finally {
-  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
Index: ckend/pom.xml
===================================================================
--- backend/pom.xml	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,140 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.5.3</version>
-        <relativePath/> <!-- lookup parent from repository -->
-    </parent>
-
-    <groupId>finki.db</groupId>
-    <artifactId>Tasty_Tabs</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <name>Tasty Tabs</name>
-    <description>Tasty Tabs</description>
-
-    <properties>
-        <java.version>17</java.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jdbc</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jpa</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.flywaydb</groupId>
-            <artifactId>flyway-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.flywaydb</groupId>
-            <artifactId>flyway-database-postgresql</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-devtools</artifactId>
-            <scope>runtime</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-configuration-processor</artifactId>
-            <optional>true</optional>
-        </dependency>
-
-        <!-- ✅ Fixed Lombok dependency -->
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.18.34</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springdoc</groupId>
-            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
-            <version>2.3.0</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.datatype</groupId>
-            <artifactId>jackson-datatype-jsr310</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-api</artifactId>
-            <version>0.11.2</version>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-impl</artifactId>
-            <version>0.11.2</version>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-jackson</artifactId>
-            <version>0.11.2</version>
-            <scope>runtime</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <!-- ✅ Added version and ensured Lombok is included in annotation processing -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.11.0</version>
-                <configuration>
-                    <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.springframework.boot</groupId>
-                            <artifactId>spring-boot-configuration-processor</artifactId>
-                        </path>
-                        <path>
-                            <groupId>org.projectlombok</groupId>
-                            <artifactId>lombok</artifactId>
-                            <version>1.18.34</version>
-                        </path>
-                    </annotationProcessorPaths>
-                </configuration>
-            </plugin>
-
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
Index: ckend/src/main/java/finki/db/tasty_tabs/TastyTabsApplication.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/TastyTabsApplication.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class TastyTabsApplication {
-
-    public static void main(String[] args) {
-        SpringApplication.run(TastyTabsApplication.class, args);
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/aspect/annotation/CheckOnDuty.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/aspect/annotation/CheckOnDuty.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package finki.db.tasty_tabs.aspect.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marks a method that requires the employee to be on an active shift.
- * The aspect associated with this annotation will verify the employee's status
- * before allowing the method to execute.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface CheckOnDuty {
-    /**
-     * Specifies the name of the method parameter that holds the employee's ID.
-     * Defaults to "employeeId". This parameter must be of type Long.
-     * @return The parameter name for the employee ID.
-     */
-    String employeeIdParamName() default "employeeId";
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/aspect/annotation/OnDutyAspect.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/aspect/annotation/OnDutyAspect.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,45 +1,0 @@
-package finki.db.tasty_tabs.aspect.annotation;
-
-import finki.db.tasty_tabs.aspect.annotation.CheckOnDuty;
-import finki.db.tasty_tabs.entity.exceptions.EmployeeNotOnDutyException;
-import finki.db.tasty_tabs.service.EmployeeService;
-import finki.db.tasty_tabs.web.security.AuthenticatedUser;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.springframework.security.authentication.InsufficientAuthenticationException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-
-@Aspect
-@Component
-public class OnDutyAspect {
-
-    private final EmployeeService employeeService;
-
-    public OnDutyAspect(EmployeeService employeeService) {
-        this.employeeService = employeeService;
-    }
-
-    /**
-     * This advice runs before any method annotated with @CheckOnDuty.
-     * It retrieves the currently logged-in user from the SecurityContext,
-     * checks if they are on an active shift, and throws an exception if not.
-     */
-    @Before("@annotation(finki.db.tasty_tabs.aspect.annotation.CheckOnDuty)")
-    public void checkIsOnDuty() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-
-        // Check if the user is authenticated at all
-        if (authentication == null || !authentication.isAuthenticated() || !(authentication.getPrincipal() instanceof AuthenticatedUser currentUser)) {
-            throw new InsufficientAuthenticationException("User must be authenticated to perform this action.");
-        }
-
-        // Get the custom principal object
-        Long employeeId = currentUser.getId();
-
-        if (!employeeService.isOnActiveShift(employeeId)) {
-            throw new EmployeeNotOnDutyException("Employee with ID " + employeeId + " is not on an active shift.");
-        }
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/config/OpenApiConfig.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/config/OpenApiConfig.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,50 +1,0 @@
-package finki.db.tasty_tabs.config;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyNamingStrategies;
-import io.swagger.v3.core.jackson.ModelResolver;
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.media.StringSchema;
-import io.swagger.v3.oas.models.parameters.Parameter;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import org.springdoc.core.customizers.OpenApiCustomizer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.List;
-
-@Configuration
-public class OpenApiConfig {
-
-    @Bean
-    public ModelResolver modelResolver(ObjectMapper objectMapper) {
-        return new ModelResolver(objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE));
-    }
-
-    @Bean
-    public OpenApiCustomizer globalHeaderCustomizer() {
-        return openApi -> {
-            // No action is performed here, effectively removing the global parameter
-        };
-    }
-
-    @Bean
-    public OpenAPI customOpenAPI() {
-        return new OpenAPI()
-                .components(new Components()
-                        .addSecuritySchemes("bearerAuth",
-                                new SecurityScheme()
-                                        .type(SecurityScheme.Type.HTTP)
-                                        .scheme("bearer")
-                                        .bearerFormat("JWT")
-                        )
-                )
-                .addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
-                .addServersItem(new Server().url("http://localhost:8080").description("Local server"));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/config/WebConfig.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/config/WebConfig.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package finki.db.tasty_tabs.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-@Configuration
-public class WebConfig implements WebMvcConfigurer {
-
-    public WebConfig() {
-    }
-
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**")
-                .allowedOrigins("*")
-                .allowedMethods("*")
-                .allowedHeaders("*")
-                .allowCredentials(false)
-                .maxAge(3600);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Assignment.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Assignment.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,104 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-
-/**
- * Entity: Assignment
- * Description: Represents shift assignment for each employee.
- */
-@Entity
-@Table(name = "assignments")
-@Data
-@NoArgsConstructor
-public class Assignment {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "clock_in_time")
-    private LocalDateTime clockInTime;
-
-    @Column(name = "clock_out_time")
-    private LocalDateTime clockOutTime;
-
-    @ManyToOne
-    @JoinColumn(name = "manager_id", referencedColumnName = "employee_id", nullable = false)
-    private Manager manager;
-
-    @ManyToOne
-    @JoinColumn(name = "employee_id", referencedColumnName = "user_id", nullable = false)
-    private Employee employee;
-
-    @ManyToOne
-    @JoinColumn(name = "shift_id", referencedColumnName = "id", nullable = false)
-    private Shift shift;
-
-    public Assignment(LocalDateTime clockInTime, LocalDateTime clockOutTime, Employee employee, Shift shift) {
-        this.clockInTime = clockInTime;
-        this.clockOutTime = clockOutTime;
-        this.employee = employee;
-        this.shift = shift;
-    }
-
-    public Assignment(LocalDateTime clockInTime, LocalDateTime clockOutTime, Manager manager, Employee employee, Shift shift) {
-        this.clockInTime = clockInTime;
-        this.clockOutTime = clockOutTime;
-        this.manager = manager;
-        this.employee = employee;
-        this.shift = shift;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public LocalDateTime getClockInTime() {
-        return clockInTime;
-    }
-
-    public void setClockInTime(LocalDateTime clockInTime) {
-        this.clockInTime = clockInTime;
-    }
-
-    public LocalDateTime getClockOutTime() {
-        return clockOutTime;
-    }
-
-    public void setClockOutTime(LocalDateTime clockOutTime) {
-        this.clockOutTime = clockOutTime;
-    }
-
-    public Manager getManager() {
-        return manager;
-    }
-
-    public void setManager(Manager manager) {
-        this.manager = manager;
-    }
-
-    public Employee getEmployee() {
-        return employee;
-    }
-
-    public void setEmployee(Employee employee) {
-        this.employee = employee;
-    }
-
-    public Shift getShift() {
-        return shift;
-    }
-
-    public void setShift(Shift shift) {
-        this.shift = shift;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/BackStaff.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/BackStaff.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-/**
- * Entity: BackStaff
- * Description: A disjoint specialization of the Employee entity for back-office staff members.
- */
-@Entity
-@Table(name = "back_staff")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "user_id")
-public class BackStaff extends Employee {
-
-    @ManyToOne
-    @JoinColumn(name = "staff_role_id", referencedColumnName = "id")
-    private StaffRole staffRole;
-
-    public UserType getUserType() {
-        return UserType.BACK_STAFF;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Category.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Category.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,37 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-import com.fasterxml.jackson.annotation.JsonManagedReference;
-import jakarta.persistence.*;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Category
- */
-@Entity
-@Table(name = "categories")
-@Data
-@NoArgsConstructor
-public class Category {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(nullable = false, unique = true)
-    private String name;
-
-    @Column(name = "is_available")
-    private Boolean isAvailable;
-
-    @OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
-    @JsonManagedReference
-    private List<Product> products;
-
-    public Category(String name, Boolean isAvailable) {
-        this.name = name;
-        this.isAvailable = isAvailable;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Customer.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Customer.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Customer
- * Description: Represents customers in the system. Inherits from User.
- */
-@Entity
-@Table(name = "customers")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "user_id") // Links to the User table
-public class Customer extends User {
-    
-    // Relationship for online orders placed by this customer
-    @OneToMany(mappedBy = "customer")
-    private List<OnlineOrder> onlineOrders;
-
-    public UserType getUserType() {
-        return UserType.CUSTOMER;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Employee.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Employee.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,83 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Employee
- * Description: Represents employees of the system. Inherits from User.
- */
-@Entity
-@Table(name = "employees")
-@Data
-@PrimaryKeyJoinColumn(name = "user_id") // Links to the User table
-public class Employee extends User {
-
-    @Column(name = "net_salary", nullable = false)
-    private Double netSalary;
-
-    @Column(name = "gross_salary", nullable = false)
-    private Double grossSalary;
-
-    @OneToMany(mappedBy = "employee")
-    private List<Order> tabOrders;
-
-    // Relationship for assignments given to this employee
-    @OneToMany(mappedBy = "employee")
-    private List<Assignment> assignments;
-
-    public List<Order> getTabOrders() {
-        return tabOrders;
-    }
-
-    public void setTabOrders(List<Order> tabOrders) {
-        this.tabOrders = tabOrders;
-    }
-
-    public Employee() {
-        super();
-    }
-    public Employee(Double netSalary, Double grossSalary) {
-        super();
-        this.netSalary = netSalary;
-        this.grossSalary = grossSalary;
-    }
-
-    public Employee(String email, String street, String city, String phoneNumber, Double netSalary, Double grossSalary, List<Assignment> assignments) {
-        super(email, street, city, phoneNumber);
-        this.netSalary = netSalary;
-        this.grossSalary = grossSalary;
-        this.assignments = assignments;
-    }
-
-    public Double getNetSalary() {
-        return netSalary;
-    }
-
-    public List<Assignment> getAssignments() {
-        return assignments;
-    }
-
-    public void setAssignments(List<Assignment> assignments) {
-        this.assignments = assignments;
-    }
-
-    public void setNetSalary(Double netSalary) {
-        this.netSalary = netSalary;
-    }
-
-    public Double getGrossSalary() {
-        return grossSalary;
-    }
-
-    public void setGrossSalary(Double grossSalary) {
-        this.grossSalary = grossSalary;
-    }
-
-    public UserType getUserType(){
-        return UserType.EMPLOYEE;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/EmployeeType.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/EmployeeType.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,5 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-public enum EmployeeType {
-    MANAGER, FRONT_STAFF, BACK_STAFF
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/FrontStaff.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/FrontStaff.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,60 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: FrontStaff
- * Description: A disjoint specialization of the Employee entity for front-facing staff members.
- */
-@Entity
-@Table(name = "front_staff")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "user_id")
-public class FrontStaff extends Employee {
-
-    @Column(name = "tip_percent")
-    private Double tipPercent;
-
-    @ManyToOne
-    @JoinColumn(name = "staff_role_id", referencedColumnName = "id")
-    private StaffRole staffRole;
-
-
-    @OneToMany(mappedBy = "frontStaff")
-    private List<ReservationManagedFrontStaff> managedReservations;
-
-    public Double getTipPercent() {
-        return tipPercent;
-    }
-
-    public void setTipPercent(Double tipPercent) {
-        this.tipPercent = tipPercent;
-    }
-
-    public StaffRole getStaffRole() {
-        return staffRole;
-    }
-
-    public void setStaffRole(StaffRole staffRole) {
-        this.staffRole = staffRole;
-    }
-
-
-
-    public List<ReservationManagedFrontStaff> getManagedReservations() {
-        return managedReservations;
-    }
-
-    public void setManagedReservations(List<ReservationManagedFrontStaff> managedReservations) {
-        this.managedReservations = managedReservations;
-    }
-
-    public UserType getUserType() {
-        return UserType.FRONT_STAFF;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Inventory.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Inventory.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,69 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-/**
- * Entity: Inventory
- * Description: Tracks product quantities and restocking levels.
- */
-@Entity
-@Table(name = "inventories")
-@Data
-@NoArgsConstructor
-public class Inventory {
-
-    @Id
-    @Column(name = "product_id")
-    private Long productId;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @MapsId
-    @JoinColumn(name = "product_id")
-    private Product product;
-
-    @Column(name = "quantity", nullable = false)
-    private Integer quantity;
-
-    @Column(name = "restock_level")
-    private Integer restockLevel;
-
-    public Inventory(Product product, Integer quantity, Integer restockLevel) {
-        this.product = product;  // @MapsId ќе го земе id-то
-        this.quantity = quantity;
-        this.restockLevel = restockLevel;
-    }
-
-
-    public Long getProductId() {
-        return productId;
-    }
-
-    public void setProductId(Long productId) {
-        this.productId = productId;
-    }
-
-    public Product getProduct() {
-        return product;
-    }
-
-    public void setProduct(Product product) {
-        this.product = product;
-    }
-
-    public Integer getQuantity() {
-        return quantity;
-    }
-
-    public void setQuantity(Integer quantity) {
-        this.quantity = quantity;
-    }
-
-    public Integer getRestockLevel() {
-        return restockLevel;
-    }
-
-    public void setRestockLevel(Integer restockLevel) {
-        this.restockLevel = restockLevel;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Manager.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Manager.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,32 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Manager
- * Description: A disjoint specialization of the Employee entity for managers.
- */
-@Entity
-@Table(name = "managers")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "user_id")
-public class Manager extends Employee {
-
-    // Relationship for shifts created by this manager
-    @OneToMany(mappedBy = "manager")
-    private List<Shift> createdShifts;
-
-    // Relationship for assignments created by this manager
-    @OneToMany(mappedBy = "manager")
-    private List<Assignment> createdAssignments;
-
-
-    public UserType getUserType() {
-        return UserType.MANAGER;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/OnlineOrder.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/OnlineOrder.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,39 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-/**
- * Entity: OnlineOrder
- * Description: Represents orders made online by customers.
- */
-@Entity
-@Table(name = "online_orders")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "order_id")
-public class OnlineOrder extends Order {
-
-    @ManyToOne
-    @JoinColumn(name = "customer_id", referencedColumnName = "user_id", nullable = false)
-    private Customer customer;
-
-    @Column(name = "delivery_address", nullable = false)
-    private String deliveryAddress;
-
-    public Customer getCustomer() {
-        return customer;
-    }
-
-    public void setCustomer(Customer customer) {
-        this.customer = customer;
-    }
-
-    public String getDeliveryAddress() {
-        return deliveryAddress;
-    }
-
-    public void setDeliveryAddress(String deliveryAddress) {
-        this.deliveryAddress = deliveryAddress;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Order.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Order.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,89 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Entity: Order
- * Description: Represents a customer's order in the system.
- */
-@Entity
-@Table(name = "orders") // "order" is a reserved keyword
-@Data
-@NoArgsConstructor
-@Inheritance(strategy = InheritanceType.JOINED)
-public class Order {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "datetime", nullable = false)
-    private LocalDateTime timestamp;
-
-    @Column(name = "status")
-    private String status;
-
-    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
-    private List<OrderItem> orderItems = new ArrayList<>();
-
-    @OneToOne(mappedBy = "order", cascade = CascadeType.ALL)
-    private Payment payment;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "employee_id", referencedColumnName = "user_id", nullable = true)
-    private Employee employee;
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public LocalDateTime getTimestamp() {
-        return timestamp;
-    }
-
-    public void setTimestamp(LocalDateTime timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public List<OrderItem> getOrderItems() {
-        return orderItems != null ? orderItems : new ArrayList<OrderItem>();
-    }
-
-    public void setOrderItems(List<OrderItem> orderItems) {
-        this.orderItems = orderItems;
-    }
-
-    public Payment getPayment() {
-        return payment;
-    }
-
-    public Employee getEmployee() {
-        return employee;
-    }
-
-    public void setEmployee(Employee employee) {
-        this.employee = employee;
-    }
-
-    public void setPayment(Payment payment) {
-        this.payment = payment;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/OrderItem.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/OrderItem.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,42 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-
-/**
- * Entity: OrderItem
- * Description: Represents items in a customer's order.
- */
-@Entity
-@Table(name = "order_items")
-@Data
-@NoArgsConstructor
-public class OrderItem {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "quantity", nullable = false)
-    private Integer quantity;
-
-    @Column(name = "price", nullable = false)
-    private Double price;
-
-    @Column(name = "is_processed")
-    private Boolean isProcessed;
-
-    @Column(name = "created_at", nullable = false)
-    private LocalDateTime timestamp;
-
-    @ManyToOne
-    @JoinColumn(name = "product_id", referencedColumnName = "id", nullable = false)
-    private Product product;
-
-    @ManyToOne
-    @JoinColumn(name = "order_id", referencedColumnName = "id", nullable = false)
-    private Order order;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Payment.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Payment.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,87 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-
-/**
- * Entity: Payment
- * Description: Represents payments for orders.
- */
-@Entity
-@Table(name = "payments")
-@Data
-@NoArgsConstructor
-public class Payment {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "tip_amount")
-    private Double tipAmount;
-
-    @Column(name = "created_at", nullable = false)
-    private LocalDateTime timestamp;
-
-    @Column(name = "payment_type", nullable = false)
-    private String paymentType;
-
-    @Column(name = "amount", nullable = false)
-    private Double amount;
-
-    @OneToOne
-    @JoinColumn(name = "order_id", referencedColumnName = "id", nullable = false, unique = true)
-    private Order order;
-
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Double getTipAmount() {
-        return tipAmount;
-    }
-
-    public void setTipAmount(Double tipAmount) {
-        this.tipAmount = tipAmount;
-    }
-
-    public LocalDateTime getTimestamp() {
-        return timestamp;
-    }
-
-    public void setTimestamp(LocalDateTime timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    public String getPaymentType() {
-        return paymentType;
-    }
-
-    public void setPaymentType(String paymentType) {
-        this.paymentType = paymentType;
-    }
-
-    public Double getAmount() {
-        return amount;
-    }
-
-    public void setAmount(Double amount) {
-        this.amount = amount;
-    }
-
-    public Order getOrder() {
-        return order;
-    }
-
-    public void setOrder(Order order) {
-        this.order = order;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/PaymentsDailyChannel.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/PaymentsDailyChannel.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,37 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-import finki.db.tasty_tabs.entity.composite_keys.PaymentsDailyChannelId;
-import jakarta.persistence.*;
-import org.hibernate.annotations.Immutable;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "mv_payments_daily_channel")
-@IdClass(PaymentsDailyChannelId.class)
-@Immutable
-public class PaymentsDailyChannel {
-
-    @Id
-    private LocalDate day;
-
-    @Id
-    private String channel; // 'TAB' | 'ONLINE' | 'UNKNOWN'
-
-    @Column(name = "paid_orders_cnt")
-    private Long paidOrdersCnt;
-
-    private BigDecimal revenue;
-
-    @Column(name = "tip_total")
-    private BigDecimal tipTotal;
-
-    // getters only (or no setters) to keep it immutable in code
-    public LocalDate getDay() { return day; }
-    public String getChannel() { return channel; }
-    public Long getPaidOrdersCnt() { return paidOrdersCnt; }
-    public BigDecimal getRevenue() { return revenue; }
-    public BigDecimal getTipTotal() { return tipTotal; }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Product.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Product.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,48 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-import com.fasterxml.jackson.annotation.JsonBackReference;
-import jakarta.persistence.*;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Product
- */
-@Entity
-@Table(name = "products")
-@Data
-@NoArgsConstructor
-public class Product {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(nullable = false)
-    private String name;
-
-    @Column(nullable = false)
-    private Double price;
-
-    @Column(name = "tax_class")
-    private String taxClass;
-
-    @Column(length = 1024)
-    private String description = "";
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "category_id", nullable = false)
-    @JsonBackReference
-    private Category category;
-
-    @Column(name = "manage_inventory")
-    private Boolean manageInventory;
-
-    @OneToOne(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
-    private Inventory inventory;
-
-    @OneToMany(mappedBy = "product")
-    private List<OrderItem> orderItems;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Reservation.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Reservation.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,98 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-/**
- * Entity: Reservation
- * Description: Represents reservations made by users.
- */
-@Entity
-@Table(name = "reservations")
-@Data
-@NoArgsConstructor
-public class Reservation {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "stay_length")
-    private Integer stayLength;
-
-    @Column(name = "datetime", nullable = false)
-    private LocalDateTime datetime;
-
-    @Column(name = "creation_timestamp", nullable = false)
-    private LocalDateTime creationTimestamp;
-
-    @Column(name = "number_of_people", nullable = false)
-    private Integer numberOfPeople;
-
-    @ManyToOne
-    @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
-    private User user;
-
-    @OneToMany(mappedBy = "reservation")
-    private List<ReservationManagedFrontStaff> managedReservations;
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Integer getStayLength() {
-        return stayLength;
-    }
-
-    public void setStayLength(Integer stayLength) {
-        this.stayLength = stayLength;
-    }
-
-    public LocalDateTime getDatetime() {
-        return datetime;
-    }
-
-    public void setDatetime(LocalDateTime datetime) {
-        this.datetime = datetime;
-    }
-
-    public LocalDateTime getCreationTimestamp() {
-        return creationTimestamp;
-    }
-
-    public void setCreationTimestamp(LocalDateTime creationTimestamp) {
-        this.creationTimestamp = creationTimestamp;
-    }
-
-    public Integer getNumberOfPeople() {
-        return numberOfPeople;
-    }
-
-    public void setNumberOfPeople(Integer numberOfPeople) {
-        this.numberOfPeople = numberOfPeople;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public List<ReservationManagedFrontStaff> getManagedReservations() {
-        return managedReservations;
-    }
-
-    public void setManagedReservations(List<ReservationManagedFrontStaff> managedReservations) {
-        this.managedReservations = managedReservations;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/ReservationManagedFrontStaff.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/ReservationManagedFrontStaff.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package finki.db.tasty_tabs.entity;// finki.db.tasty_tabs.entity.ReservationManagedFrontStaff
-import jakarta.persistence.*;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import finki.db.tasty_tabs.entity.composite_keys.ReservationManagedFrontStaffId;
-
-@Entity
-@Table(name = "frontstaff_managed_reservations")
-@Data
-@NoArgsConstructor
-public class ReservationManagedFrontStaff {
-
-    @EmbeddedId
-    private ReservationManagedFrontStaffId id;
-
-    @ManyToOne
-    @MapsId("reservationId")
-    @JoinColumn(name = "reservation_id", referencedColumnName = "id")
-    private Reservation reservation;
-
-    @ManyToOne
-    @MapsId("frontstaffId")
-    @JoinColumn(name = "front_staff_id", referencedColumnName = "employee_id")
-    private FrontStaff frontStaff;
-
-    @ManyToOne
-    @MapsId("tableNumber")
-    @JoinColumn(name = "table_number", referencedColumnName = "table_number")
-    private RestaurantTable restaurantTable;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/RestaurantTable.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/RestaurantTable.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,36 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: Table
- * Description: Represents dining tables in the system.
- */
-@Entity
-@Table(name = "tables") // "table" is a reserved keyword
-@Data
-@NoArgsConstructor
-public class RestaurantTable {
-
-    @Id
-    @Column(name = "table_number")
-    private Long tableNumber;
-
-    @Column(name = "seat_capacity", nullable = false)
-    private Integer seatCapacity;
-
-    @OneToMany(mappedBy = "restaurantTable")
-    private List<TabOrder> tabOrders;
-
-    @OneToMany(mappedBy = "restaurantTable")
-    private List<ReservationManagedFrontStaff> managedReservations;
-
-    public RestaurantTable(Long tableNumber, Integer seatCapacity) {
-        this.tableNumber=tableNumber;
-        this.seatCapacity=seatCapacity;
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/Shift.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Shift.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,102 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Entity: Shift
- * Description: Represents a work shift in the system.
- */
-@Entity
-@Table(name = "shifts")
-@Data
-@NoArgsConstructor
-public class Shift {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "date", nullable = false)
-    private LocalDate date;
-
-    @Column(name = "start_time", nullable = false)
-    private LocalDateTime start;
-
-    @Column(name = "end_time", nullable = false)
-    private LocalDateTime end;
-
-    @ManyToOne
-    @JoinColumn(name = "manager_id", referencedColumnName = "employee_id", nullable = false)
-    private Manager manager;
-
-    @OneToMany(mappedBy = "shift")
-    private List<Assignment> assignments = new ArrayList<>();
-
-    public Shift(LocalDate date, LocalDateTime start, LocalDateTime end, Manager manager) {
-        this.date = date;
-        this.start = start;
-        this.end = end;
-        this.manager = manager;
-    }
-
-    public Shift(LocalDate date, LocalDateTime start, LocalDateTime end) {
-        this.date = date;
-        this.start = start;
-        this.end = end;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public LocalDateTime getStart() {
-        return start;
-    }
-
-    public void setStart(LocalDateTime start) {
-        this.start = start;
-    }
-
-    public LocalDateTime getEnd() {
-        return end;
-    }
-
-    public void setEnd(LocalDateTime end) {
-        this.end = end;
-    }
-
-    public Manager getManager() {
-        return manager;
-    }
-
-    public void setManager(Manager manager) {
-        this.manager = manager;
-    }
-
-    public List<Assignment> getAssignments() {
-        return assignments;
-    }
-
-    public void setAssignments(List<Assignment> assignments) {
-        this.assignments = assignments;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/StaffRole.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/StaffRole.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,31 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * Entity: StaffRole
- * Description: Defines roles for staff members.
- */
-@Entity
-@Table(name = "staff_roles")
-@Data
-@NoArgsConstructor
-public class StaffRole {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "name", nullable = false, unique = true)
-    private String name;
-
-    @OneToMany(mappedBy = "staffRole")
-    private List<FrontStaff> frontStaffs;
-
-    @OneToMany(mappedBy = "staffRole")
-    private List<BackStaff> backStaffs;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/TabOrder.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/TabOrder.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,41 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-/**
- * Entity: TabOrder
- * Description: Represents orders made at a specific table.
- */
-@Entity
-@Table(name = "tab_orders")
-@Data
-@NoArgsConstructor
-@PrimaryKeyJoinColumn(name = "order_id")
-public class TabOrder extends Order {
-
-    @ManyToOne
-    @JoinColumn(name = "table_number", referencedColumnName = "table_number", nullable = false)
-    private RestaurantTable restaurantTable;
-
-    @OneToOne
-    @MapsId
-    @JoinColumn(name = "order_id")
-    private Order order;
-
-    public Order getOrder() {
-        return order;
-    }
-
-    public void setOrder(Order order) {
-        this.order = order;
-    }
-
-    public RestaurantTable getRestaurantTable() {
-        return restaurantTable;
-    }
-
-    public void setRestaurantTable(RestaurantTable restaurantTable) {
-        this.restaurantTable = restaurantTable;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/User.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/User.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,83 +1,0 @@
-package finki.db.tasty_tabs.entity;
-import jakarta.persistence.*;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Entity: User
- * Description: Contains main information about all users in the system.
- */
-@Entity
-@Table(name = "users") // "user" is often a reserved keyword in SQL
-@Data
-@NoArgsConstructor
-@Inheritance(strategy = InheritanceType.JOINED) // Strategy to allow for Employee/Customer subtypes
-public class User {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @Column(name = "email", nullable = false, unique = true)
-    private String email;
-
-    @Column(name = "street")
-    private String street;
-
-    @Column(name = "city")
-    private String city;
-
-    @Column(name = "phone_number")
-    private String phoneNumber;
-
-    @Column(name = "password", nullable = false)
-    private String password;
-
-    // Relationship for Reservations made by a user (if they are a customer)
-    @OneToMany(mappedBy = "user")
-    private List<Reservation> reservations = new ArrayList<>();
-    public User(String email, String street, String city, String phoneNumber) {
-        this.email = email;
-        this.street = street;
-        this.city = city;
-        this.phoneNumber = phoneNumber;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public void setStreet(String street) {
-        this.street = street;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public void setPhoneNumber(String phoneNumber) {
-        this.phoneNumber = phoneNumber;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public void setReservations(List<Reservation> reservations) {
-        this.reservations = reservations;
-    }
-
-    public UserType getUserType() {
-        return UserType.USER;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/UserType.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/UserType.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.entity;
-
-public enum UserType {
-    CUSTOMER,
-    MANAGER,
-    FRONT_STAFF,
-    BACK_STAFF,
-    USER, EMPLOYEE
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/composite_keys/PaymentsDailyChannelId.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/composite_keys/PaymentsDailyChannelId.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package finki.db.tasty_tabs.entity.composite_keys;
-
-import java.io.Serializable;
-import java.time.LocalDate;
-import java.util.Objects;
-
-public class PaymentsDailyChannelId implements Serializable {
-    private LocalDate day;
-    private String channel;
-
-    public PaymentsDailyChannelId() {}
-    public PaymentsDailyChannelId(LocalDate day, String channel) {
-        this.day = day; this.channel = channel;
-    }
-
-    @Override public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof PaymentsDailyChannelId that)) return false;
-        return Objects.equals(day, that.day) && Objects.equals(channel, that.channel);
-    }
-    @Override public int hashCode() { return Objects.hash(day, channel); }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/composite_keys/ReservationManagedFrontStaffId.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/composite_keys/ReservationManagedFrontStaffId.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,40 +1,0 @@
-package finki.db.tasty_tabs.entity.composite_keys;
-import jakarta.persistence.Column;
-import jakarta.persistence.Embeddable;
-import java.io.Serializable;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import java.util.Objects;
-
-@Embeddable
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class ReservationManagedFrontStaffId implements Serializable {
-
-    @Column(name = "reservation_id")
-    private Long reservationId;
-
-    @Column(name = "front_staff_id")
-    private Long frontstaffId;
-
-    @Column(name = "table_number")
-    private Long tableNumber;
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        ReservationManagedFrontStaffId that = (ReservationManagedFrontStaffId) o;
-        return Objects.equals(reservationId, that.reservationId) &&
-                Objects.equals(frontstaffId, that.frontstaffId) &&
-                Objects.equals(tableNumber, that.tableNumber);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(reservationId, frontstaffId, tableNumber);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/AssignmentNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/AssignmentNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class AssignmentNotFoundException extends DomainException {
-
-    public AssignmentNotFoundException(Long id) {
-        super(String.format("Assignment with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/CategoryNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/CategoryNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class CategoryNotFoundException extends DomainException {
-
-    public CategoryNotFoundException(String name) {
-        super(String.format("Category: %s doesnt exist",name));
-    }
-    public CategoryNotFoundException() {
-        super("Category doesnt exist");
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/DomainException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/DomainException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public abstract class DomainException extends RuntimeException {
-    public DomainException(String message) {
-        super(message);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/EmployeeNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/EmployeeNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class EmployeeNotFoundException extends DomainException {
-
-    public EmployeeNotFoundException(Long id) {
-        super(String.format("Employee with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/EmployeeNotOnDutyException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/EmployeeNotOnDutyException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class EmployeeNotOnDutyException extends RuntimeException {
-    public EmployeeNotOnDutyException(String message) {
-        super(message);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/FrontStaffNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/FrontStaffNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class FrontStaffNotFoundException extends DomainException {
-
-    public FrontStaffNotFoundException(Long id) {
-        super(String.format("FrontStaff with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/InvalidOrderTypeException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/InvalidOrderTypeException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class InvalidOrderTypeException extends DomainException {
-
-    public InvalidOrderTypeException(String message) {
-        super(message);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/OrderItemNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/OrderItemNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class OrderItemNotFoundException extends DomainException {
-
-    public OrderItemNotFoundException() {
-        super(String.format("OrderItem doesnt exist"));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/OrderNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/OrderNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class OrderNotFoundException extends DomainException {
-
-    public OrderNotFoundException(Long id) {
-        super(String.format("Order with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/PaymentNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/PaymentNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class PaymentNotFoundException extends DomainException {
-
-    public PaymentNotFoundException(Long id) {
-        super(String.format("Payment with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ProductNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ProductNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class ProductNotFoundException extends DomainException {
-
-    public ProductNotFoundException(Long id) {
-        super(String.format("Product with id %d doesnt exist",id));
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ProductNotInStockException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ProductNotInStockException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class ProductNotInStockException extends DomainException {
-
-    public ProductNotInStockException(String name) {
-        super(String.format("Product: %s not in stock",name));
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ReservationNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ReservationNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class ReservationNotFoundException extends DomainException {
-
-    public ReservationNotFoundException(Long id) {
-        super(String.format("Reservation with id %d doesnt exist",id));
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ShiftNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/ShiftNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class ShiftNotFoundException extends DomainException {
-
-    public ShiftNotFoundException(Long id) {
-        super(String.format("Shift with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/TableNotFoundException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/TableNotFoundException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class TableNotFoundException extends DomainException {
-
-    public TableNotFoundException(Long id) {
-        super(String.format("Table with id %d doesnt exist",id));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/entity/exceptions/TableNumberAlreadyExistsException.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/exceptions/TableNumberAlreadyExistsException.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.entity.exceptions;
-
-public class TableNumberAlreadyExistsException extends DomainException {
-
-    public TableNumberAlreadyExistsException(Long number) {
-        super(String.format("Table: %d already exists", number));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsAdminRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsAdminRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,32 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-@Repository
-@RequiredArgsConstructor
-public class AnalyticsAdminRepository {
-
-    private final JdbcTemplate jdbcTemplate;
-
-    /** Non-blocking for readers; must run outside a transaction */
-    @Transactional(propagation = Propagation.NOT_SUPPORTED)
-    public void refreshMvPaymentsDailyChannelConcurrently() {
-        jdbcTemplate.update("REFRESH MATERIALIZED VIEW CONCURRENTLY mv_payments_daily_channel");
-    }
-
-    /** Blocking for readers; can run inside a transaction */
-    @Transactional
-    public void refreshMvPaymentsDailyChannel() {
-        jdbcTemplate.update("REFRESH MATERIALIZED VIEW mv_payments_daily_channel");
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsReadRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsReadRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,261 +1,0 @@
-package finki.db.tasty_tabs.repository;
-import finki.db.tasty_tabs.web.dto.*;
-import lombok.RequiredArgsConstructor;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Repository;
-
-import java.sql.ResultSet;
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-@Repository
-@RequiredArgsConstructor
-public class AnalyticsReadRepository {
-
-    private final JdbcTemplate jdbc;
-
-    public List<ServerPerformanceDto> serverPerformanceLast3Months() {
-        String sql = """
-        WITH server_metrics AS (
-            SELECT
-                fs.employee_id,
-                u.email as server_email,
-                COUNT(DISTINCT a.id) as total_assignments,
-                COUNT(DISTINCT o.id) as orders_processed,
-                COALESCE(SUM(oi.quantity * oi.price), 0) as total_revenue_generated
-            FROM front_staff fs
-            JOIN employees e ON fs.employee_id = e.user_id
-            JOIN users u ON e.user_id = u.id
-            JOIN staff_roles sr ON fs.staff_role_id = sr.id
-            LEFT JOIN assignments a ON fs.employee_id = a.employee_id
-            LEFT JOIN shifts s ON a.shift_id = s.id
-            LEFT JOIN orders o ON o.employee_id = fs.employee_id
-               AND o.datetime >= CURRENT_DATE - INTERVAL '3 months'
-            LEFT JOIN order_items oi ON o.id = oi.order_id
-            WHERE LOWER(sr.name) = 'server'
-            GROUP BY fs.employee_id, u.email, u.phone_number,
-                     e.net_salary, e.gross_salary, fs.tip_percent, sr.name
-        ),
-        performance_ranking AS (
-            SELECT *,
-                RANK() OVER (ORDER BY total_revenue_generated DESC) as revenue_rank,
-                RANK() OVER (ORDER BY orders_processed DESC) as orders_rank,
-                CASE WHEN total_assignments > 0
-                     THEN (orders_processed::float / total_assignments)
-                     ELSE 0 END as orders_per_assignment,
-                CASE WHEN orders_processed > 0
-                     THEN total_revenue_generated / orders_processed
-                     ELSE 0 END as avg_revenue_per_order
-            FROM server_metrics
-        )
-        SELECT
-            server_email,
-            total_assignments,
-            orders_processed,
-            total_revenue_generated,
-            revenue_rank,
-            orders_rank,
-            ROUND(orders_per_assignment::numeric, 2) as avg_orders_per_shift,
-            ROUND(avg_revenue_per_order::numeric, 2) as avg_order_value
-        FROM performance_ranking
-        ORDER BY total_revenue_generated DESC, orders_processed DESC
-        """;
-        return jdbc.query(sql, (rs, i) -> new ServerPerformanceDto(
-                rs.getString("server_email"),
-                getLong(rs, "total_assignments"),
-                getLong(rs, "orders_processed"),
-                rs.getBigDecimal("total_revenue_generated"),
-                rs.getInt("revenue_rank"),
-                rs.getInt("orders_rank"),
-                rs.getBigDecimal("avg_orders_per_shift"),
-                rs.getBigDecimal("avg_order_value")
-        ));
-    }
-    public List<MonthlyRevenueVsLaborDto> monthlyRevenueVsLabor() {
-        String sql = """
-            WITH monthly_revenue AS (
-                SELECT DATE_TRUNC('month', o.datetime) as operation_month,
-                       SUM(oi.quantity * oi.price) as revenue
-                FROM orders o
-                JOIN order_items oi ON o.id = oi.order_id
-                GROUP BY DATE_TRUNC('month', o.datetime)
-            ),
-            monthly_labor_cost AS (
-                SELECT monthly_assignments.operation_month,
-                       SUM(e.gross_salary) as labor_cost
-                FROM (
-                    SELECT DISTINCT DATE_TRUNC('month', s.date) as operation_month, a.employee_id
-                    FROM shifts s
-                    JOIN assignments a ON s.id = a.shift_id
-                ) monthly_assignments
-                JOIN employees e ON monthly_assignments.employee_id = e.user_id
-                GROUP BY monthly_assignments.operation_month
-            )
-            SELECT TO_CHAR(COALESCE(mr.operation_month, mlc.operation_month), 'YYYY-MM') as period,
-                   ROUND(COALESCE(mr.revenue, 0)::numeric, 2) as total_revenue,
-                   ROUND(COALESCE(mlc.labor_cost, 0)::numeric, 2) as total_labor_cost,
-                   ROUND(
-                     CASE WHEN COALESCE(mr.revenue, 0) > 0
-                          THEN (COALESCE(mlc.labor_cost, 0) / mr.revenue * 100)
-                          ELSE 0 END::numeric, 2
-                   ) as labor_as_percent_of_revenue
-            FROM monthly_revenue mr
-            FULL OUTER JOIN monthly_labor_cost mlc ON mr.operation_month = mlc.operation_month
-            ORDER BY period DESC
-            """;
-        return jdbc.query(sql, (rs, i) -> new MonthlyRevenueVsLaborDto(
-                rs.getString("period"),
-                rs.getBigDecimal("total_revenue"),
-                rs.getBigDecimal("total_labor_cost"),
-                rs.getBigDecimal("labor_as_percent_of_revenue")
-        ));
-    }
-
-    public List<DailyOpsDto> dailyOpsSummary(int daysBack) {
-        String sql = """
-        SELECT
-            dates.operation_date,
-            COUNT(DISTINCT r.id) as total_reservations,
-            COUNT(DISTINCT o.id) as total_orders,
-            COUNT(DISTINCT r.user_id) as unique_customers,
-            COUNT(DISTINCT a.employee_id) as active_employees,
-            COALESCE(SUM(oi.quantity * oi.price), 0) as daily_revenue
-        FROM generate_series(
-            CURRENT_DATE - (? || ' days')::interval,
-            CURRENT_DATE,
-            '1 day'::interval
-        ) dates(operation_date)
-        LEFT JOIN reservations r ON DATE(r.datetime) = dates.operation_date
-        LEFT JOIN orders o ON DATE(o.datetime) = dates.operation_date
-        LEFT JOIN order_items oi ON o.id = oi.order_id
-        LEFT JOIN shifts s ON DATE(s.date) = dates.operation_date
-        LEFT JOIN assignments a ON s.id = a.shift_id
-        GROUP BY dates.operation_date
-        ORDER BY dates.operation_date DESC
-        """;
-        return jdbc.query(sql, ps -> ps.setInt(1, daysBack), (rs, i) -> new DailyOpsDto(
-                rs.getDate("operation_date").toLocalDate(),
-                getLong(rs, "total_reservations"),
-                getLong(rs, "total_orders"),
-                getLong(rs, "unique_customers"),
-                getLong(rs, "active_employees"),
-                rs.getBigDecimal("daily_revenue")
-        ));
-    }
-    public List<TopProductDto> topProducts(int daysBack, int limit) {
-        String sql = """
-            SELECT
-                p.id as product_id,
-                p.name as product_name,
-                c.name as category_name,
-                SUM(oi.quantity) as total_quantity_sold,
-                SUM(oi.quantity * oi.price) as total_revenue,
-                ROUND(100.0 * SUM(oi.quantity * oi.price) / SUM(SUM(oi.quantity * oi.price)) OVER (), 2) as revenue_share_percent
-            FROM products p
-            JOIN categories c ON p.category_id = c.id
-            JOIN order_items oi ON p.id = oi.product_id
-            JOIN orders o ON o.id = oi.order_id
-            WHERE o.datetime >= CURRENT_DATE - (? || ' days')::interval
-            GROUP BY p.id, p.name, c.name
-            ORDER BY total_revenue DESC
-            LIMIT ?
-            """;
-        return jdbc.query(sql, ps -> { ps.setInt(1, daysBack); ps.setInt(2, limit); }, (rs, i) -> new TopProductDto(
-                rs.getLong("product_id"),
-                rs.getString("product_name"),
-                rs.getString("category_name"),
-                getLong(rs, "total_quantity_sold"),
-                rs.getBigDecimal("total_revenue"),
-                rs.getBigDecimal("revenue_share_percent")
-        ));
-    }
-
-    public List<Map<String, Object>> revenueByShiftPeriodView() {
-        // dynamic columns -> return as list of maps
-        return jdbc.queryForList("SELECT * FROM v_revenue_by_shift_period");
-    }
-
-    public List<RevenueSplitDto> revenueSplit(LocalDate from, LocalDate to) {
-        return jdbc.query("SELECT * FROM get_revenue_split(?, ?)",
-                ps -> { ps.setObject(1, from); ps.setObject(2, to); },
-                (rs, i) -> new RevenueSplitDto(
-                        rs.getString("order_type"),
-                        rs.getBigDecimal("total_revenue")
-                ));
-    }
-
-    public List<ManagerShiftAboveAvgDto> managersShiftsAboveMonthlyAvgCurrentYear() {
-        String sql = """
-        WITH manager_worked_shifts AS (
-          SELECT DISTINCT
-                 s.id AS shift_id,
-                 s.date,
-                 s.start_time,
-                 s.end_time,
-                 a.employee_id AS manager_id
-          FROM assignments a
-          JOIN shifts s   ON s.id = a.shift_id
-          JOIN managers m ON m.employee_id = a.employee_id
-          WHERE s.date >= date_trunc('year', CURRENT_DATE)::date
-            AND s.date <  (date_trunc('year', CURRENT_DATE) + INTERVAL '1 year')::date
-        ),
-        shift_revenue AS (
-          SELECT
-            mws.shift_id,
-            date_trunc('month', mws.date)::date AS month_start,
-            mws.date AS shift_date,
-            mws.start_time,
-            mws.end_time,
-            mws.manager_id,
-            COALESCE(SUM(oi.quantity * oi.price), 0)::numeric(14,2) AS shift_revenue
-          FROM manager_worked_shifts mws
-          LEFT JOIN orders o
-            ON o.datetime::date = mws.date
-           AND o.datetime::time >= mws.start_time
-           AND o.datetime::time <  mws.end_time
-          LEFT JOIN order_items oi ON oi.order_id = o.id
-          GROUP BY mws.shift_id, month_start, mws.date, mws.start_time, mws.end_time, mws.manager_id
-        ),
-        monthly_avg AS (
-          SELECT month_start, AVG(shift_revenue)::numeric(14,2) AS avg_revenue_per_shift
-          FROM shift_revenue
-          GROUP BY month_start
-        )
-        SELECT
-          to_char(sr.month_start, 'YYYY-MM') AS period,
-          sr.shift_id,
-          sr.shift_date,
-          sr.start_time AS shift_start_time,
-          sr.end_time   AS shift_end_time,
-          u.email AS manager_email,
-          sr.shift_revenue,
-          ma.avg_revenue_per_shift,
-          (sr.shift_revenue - ma.avg_revenue_per_shift)::numeric(14,2) AS above_by
-        FROM shift_revenue sr
-        JOIN monthly_avg ma ON ma.month_start = sr.month_start
-        JOIN managers m     ON m.employee_id = sr.manager_id
-        JOIN employees e    ON e.user_id     = m.employee_id
-        JOIN users u        ON u.id          = e.user_id
-        WHERE sr.shift_revenue > ma.avg_revenue_per_shift
-        ORDER BY period DESC, sr.shift_revenue DESC, sr.shift_date DESC
-        """;
-
-        return jdbc.query(sql, (rs, i) -> new ManagerShiftAboveAvgDto(
-                rs.getString("period"),
-                rs.getLong("shift_id"),
-                rs.getDate("shift_date").toLocalDate(),
-                rs.getObject("shift_start_time", java.time.LocalTime.class),
-                rs.getObject("shift_end_time",   java.time.LocalTime.class),
-                rs.getString("manager_email"),
-                rs.getBigDecimal("shift_revenue"),
-                rs.getBigDecimal("avg_revenue_per_shift"),
-                rs.getBigDecimal("above_by")
-        ));
-    }
-
-    private static Long getLong(ResultSet rs, String col) throws java.sql.SQLException {
-        long v = rs.getLong(col);
-        return rs.wasNull() ? null : v;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/AssignmentRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/AssignmentRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,16 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.ShiftDto;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface AssignmentRepository extends JpaRepository<Assignment, Long> {
-    Optional<Assignment> findByEmployeeIdAndShiftId(Long employeeId, Long shiftId);
-
-    Optional<Assignment> findFirstByEmployee_IdOrderByShiftStartAsc(Long employeeId);
-    Optional<Assignment> findFirstByEmployee_IdAndClockOutTimeNullOrderByShiftStartAsc(Long employeeId);
-    Optional<Assignment> findFirstByEmployee_IdAndClockInTimeNotNullAndClockOutTimeNull(Long employeeId);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/BackStaffRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/BackStaffRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.BackStaff;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface BackStaffRepository extends JpaRepository<BackStaff, Long> {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/CategoryRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/CategoryRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,44 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Category;
-import jakarta.transaction.Transactional;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-import java.util.Optional;
-
-@Repository
-public interface CategoryRepository extends JpaRepository<Category, Long> {
-
-    Optional<Category> findByName(String name);
-    @Query(value = "SELECT * FROM category WHERE id = :id", nativeQuery = true)
-    Category customFindCategoryById(@Param("id") Long id);
-
-    @Query(value = "SELECT * FROM category", nativeQuery = true)
-    List<Category> customFindAllCategories();
-
-    // Custom INSERT (note: JPA doesn't usually do INSERT via query, so avoid this if possible)
-    @Modifying
-    @Transactional
-    @Query(value = "INSERT INTO category (name, is_available) VALUES (:name, :isAvailable)", nativeQuery = true)
-    void customInsertCategory(@Param("name") String name, @Param("isAvailable") Boolean isAvailable);
-
-    @Modifying
-    @Transactional
-    @Query(value = "UPDATE category SET name = :name, is_available = :isAvailable WHERE id = :id", nativeQuery = true)
-    int customUpdateCategory(@Param("id") Long id,
-                       @Param("name") String name,
-                       @Param("isAvailable") Boolean isAvailable);
-
-    @Modifying
-    @Transactional
-    @Query(value = "DELETE FROM category WHERE id = :id", nativeQuery = true)
-    int customDeleteCategoryById(@Param("id") Long id);
-
-    @Query(value = "SELECT * FROM category WHERE name = :name", nativeQuery = true)
-    Category customFindCategoryByName(@Param("name") String name);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/CustomerRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/CustomerRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Customer;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface CustomerRepository extends JpaRepository<Customer, Long> {}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/EmployeeRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/EmployeeRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Employee;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/FrontStaffRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/FrontStaffRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.FrontStaff;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface FrontStaffRepository extends JpaRepository<FrontStaff, Long> {}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/InventoryRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/InventoryRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Inventory;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface InventoryRepository extends JpaRepository<Inventory,Long> {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/ManagerRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/ManagerRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Manager;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface ManagerRepository extends JpaRepository<Manager, Long> {
-    Optional<Manager> findByEmail(String email);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/OnlineOrderRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/OnlineOrderRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Customer;
-import finki.db.tasty_tabs.entity.OnlineOrder;
-import finki.db.tasty_tabs.entity.Order;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Collection;
-import java.util.List;
-
-public interface OnlineOrderRepository extends JpaRepository<OnlineOrder, Long> {
-
-    List<OnlineOrder> findAllByCustomer_Id(Long id);
-
-    List<OnlineOrder> findAllByStatusIn(Collection<String> statuses);
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/OrderItemRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/OrderItemRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Order;
-import finki.db.tasty_tabs.entity.OrderItem;
-import finki.db.tasty_tabs.entity.Product;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface OrderItemRepository extends JpaRepository<OrderItem, Long> {
-    Optional<OrderItem> findByOrderAndProduct(Order order, Product product);
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/OrderRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/OrderRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Order;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.List;
-
-public interface OrderRepository extends JpaRepository<Order, Long> {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/PaymentRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/PaymentRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Payment;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.Optional;
-@Repository
-public interface PaymentRepository extends JpaRepository<Payment, Long> {
-    // Find a payment by its associated order ID
-    Optional<Payment> findByOrderId(Long orderId);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/PaymentsDailyChannelRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/PaymentsDailyChannelRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,20 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.PaymentsDailyChannel;
-import finki.db.tasty_tabs.entity.composite_keys.PaymentsDailyChannelId;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.stereotype.Repository;
-
-import java.time.LocalDate;
-import java.util.List;
-@Repository
-public interface PaymentsDailyChannelRepository
-        extends JpaRepository<PaymentsDailyChannel, PaymentsDailyChannelId> {
-
-    @Query("select p from PaymentsDailyChannel p " +
-            "where p.day between :from and :to " +
-            "and (:channel is null or p.channel = :channel) " +
-            "order by p.day asc, p.channel asc")
-    List<PaymentsDailyChannel> findRange(LocalDate from, LocalDate to, String channel);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/ProductRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/ProductRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Product;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface ProductRepository extends JpaRepository<Product, Long> {
-    List<Product> findAllByName(String name);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/ReservationManagedFrontStaffRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/ReservationManagedFrontStaffRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.ReservationManagedFrontStaff;
-import finki.db.tasty_tabs.entity.composite_keys.ReservationManagedFrontStaffId;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.Optional;
-
-@Repository
-public interface ReservationManagedFrontStaffRepository extends JpaRepository<ReservationManagedFrontStaff, ReservationManagedFrontStaffId> {
-    boolean existsByReservation_Id(Long reservationId);
-    Optional<ReservationManagedFrontStaff> findFirstByReservation_Id(Long reservationId);
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/ReservationRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/ReservationRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Reservation;
-import finki.db.tasty_tabs.entity.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-import java.time.LocalDateTime;
-import java.util.List;
-
-public interface ReservationRepository extends JpaRepository<Reservation, Long> {
-    List<Reservation> findAllByUser(User user);
-    List<Reservation> findAllByDatetimeBetween(LocalDateTime start, LocalDateTime end);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/RestaurantTableRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/RestaurantTableRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface RestaurantTableRepository extends JpaRepository<RestaurantTable, Long> {
-
-    List<RestaurantTable> findAllBySeatCapacity(Integer seatCapacity);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/ShiftRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/ShiftRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.Shift;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface ShiftRepository extends JpaRepository<Shift, Long> {}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/StaffRoleRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/StaffRoleRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.StaffRole;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface StaffRoleRepository extends JpaRepository<StaffRole, Long> {} // Added
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/TabOrderRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/TabOrderRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.OnlineOrder;
-import finki.db.tasty_tabs.entity.TabOrder;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.List;
-
-public interface TabOrderRepository extends JpaRepository<TabOrder, Long> {
-    List<TabOrder> findByRestaurantTable_TableNumberAndTimestampBetween(Integer tableNumber, LocalDateTime startOfDay, LocalDateTime endOfDay);
-    List<TabOrder> findAllByOrder_Employee_Id(Long employeeId);
-    List<TabOrder> findAllByStatus(String status);
-
-    List<TabOrder> findAllByStatusIn(Collection<String> statuses);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/repository/UserRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/UserRepository.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.repository;
-
-import finki.db.tasty_tabs.entity.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface UserRepository extends JpaRepository<User, Long> {
-    Optional<User> findByEmail(String email);
-
-    boolean existsByEmail(String email);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/AnalyticsExtraService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/AnalyticsExtraService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.web.dto.*;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-public interface AnalyticsExtraService {
-    List<ServerPerformanceDto> serverPerformanceLast3Months();
-    List<MonthlyRevenueVsLaborDto> monthlyRevenueVsLabor();
-    List<DailyOpsDto> dailyOpsSummary(int daysBack);
-    List<TopProductDto> topProducts(int daysBack, int limit);
-    List<Map<String,Object>> revenueByShiftPeriodView();
-    List<RevenueSplitDto> revenueSplit(LocalDate from, LocalDate to);
-    List<ManagerShiftAboveAvgDto> managersShiftsAboveMonthlyAvgCurrentYear();
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/AnalyticsService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/AnalyticsService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.web.dto.AnalyticsByChannelResponse;
-
-import java.time.LocalDate;
-
-public interface AnalyticsService {
-    AnalyticsByChannelResponse getPaymentsDailyChannel(LocalDate from, LocalDate to);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/AssignmentService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/AssignmentService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,18 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.web.dto.CreateAssignmentDto;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-public interface AssignmentService {
-    List<Assignment> getAllAssignments();
-    Assignment getAssignmentById(Long id);
-    Assignment createAssignment(CreateAssignmentDto dto, String managerEmail);
-    Assignment updateAssignment(Long id, CreateAssignmentDto dto, String managerEmail);
-    void deleteAssignment(Long id, String managerEmail);
-    // New method for employee to clock in/out
-    Assignment clockInShift(Long assignmentId, String employeeEmail, LocalDateTime clockInTime);
-    Assignment clockOutShift(Long assignmentId, String employeeEmail, LocalDateTime clockOutTime);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/AuthService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/AuthService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.web.dto.AuthDto;
-import finki.db.tasty_tabs.web.dto.request.RegisterRequest;
-import finki.db.tasty_tabs.web.dto.UserDto;
-
-public interface AuthService {
-    AuthDto authenticate(String username, String password);
-    AuthDto register(RegisterRequest request);
-    UserDto getAuthenticatedUser();
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/CategoryService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/CategoryService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Category;
-
-import java.util.List;
-import java.util.Optional;
-
-public interface CategoryService {
-    Category findById(Long id);
-    List<Category> getAllCategories();
-    Category updateCategory(Long id,Category category);
-    void deleteCategory(Long id);
-    Category getCategoryByName(String name);
-    Category createCategory(Category category);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/EmployeeService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/EmployeeService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,16 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.CreateEmployeeRequest;
-import finki.db.tasty_tabs.web.dto.EmployeeDto;
-
-import java.util.List;
-
-public interface EmployeeService { // New Service
-    List<EmployeeDto> getAllEmployees();
-    Employee createEmployee(CreateEmployeeRequest request);
-
-    AssignmentDto getNextShiftForEmployee(Long employeeId);
-    boolean isOnActiveShift(Long employeeId);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/OrderService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/OrderService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,45 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.*;
-import finki.db.tasty_tabs.web.dto.CreateOrderDto;
-import finki.db.tasty_tabs.web.dto.CreateOrderItemDto;
-
-import java.time.LocalDate;
-import java.util.List;
-
-public interface OrderService {
-    List<Order> findAll();
-    Order findById(Long id);
-
-    Order updateOrder(Long id, CreateOrderDto dto);
-    void deleteOrder(Long id);
-
-    double calculateTotalPrice(Long orderId);
-    void updateOrderStatus(Long orderId, String newStatus);
-
-    // Methods for Order Items
-    OrderItem addItemToOrder(Long orderId, CreateOrderItemDto itemDto);
-    void decreaseOrderItemQuantity(Long orderItemId);
-    OrderItem updateOrderItem(Long orderItemId, CreateOrderItemDto itemDto);
-    void deleteOrderItem(Long orderItemId);
-    OrderItem processOrderItem(Long orderItemId);
-
-    // Specific OnlineOrder methods
-    OnlineOrder createOnlineOrder(CreateOrderDto dto, String userEmail);
-    OnlineOrder findOnlineOrderById(Long id);
-    List<OnlineOrder> findAllOnlineOrders();
-    List<OnlineOrder> findOnlineOrdersByCustomer(Long customerId);
-
-    // Specific TabOrder methods
-    TabOrder createTabOrder(CreateOrderDto dto, String userEmail);
-    TabOrder findTabOrderById(Long id);
-    List<TabOrder> findAllTabOrders();
-    List<TabOrder> findTabOrdersByTableAndDate(Integer tableNumber, LocalDate date);
-    List<TabOrder> findTabOrdersByStaff(Long frontStaffId);
-
-    List<Order> findOpenOrders();
-    List<Order> findClosedOrders();
-
-    // General methods for all order types
-    Order cancelOrder(Long orderId);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/PaymentService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/PaymentService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Payment;
-import finki.db.tasty_tabs.web.dto.CreatePaymentDto;
-
-import java.util.List;
-
-public interface PaymentService {
-    Payment createPayment(CreatePaymentDto dto);
-    Payment findPaymentById(Long id);
-    Payment findPaymentByOrderId(Long orderId);
-    List<Payment> findAllPayments();
-    Payment updatePayment(Long id, CreatePaymentDto dto);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/ProductService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/ProductService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Product;
-import finki.db.tasty_tabs.web.dto.CreateProductDto;
-
-import java.util.List;
-
-public interface ProductService {
-    Product findById(Long id);
-    List<Product> getAllProducts();
-    Product updateProduct(Long id, CreateProductDto dto);
-    void deleteProduct(Long id);
-    List<Product> getProductsByName(String name);
-    Product createProduct(CreateProductDto dto);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/ReservationService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/ReservationService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Reservation;
-import finki.db.tasty_tabs.entity.ReservationManagedFrontStaff;
-import finki.db.tasty_tabs.web.dto.CreateReservationDto;
-import finki.db.tasty_tabs.web.dto.ReservationDto;
-
-import java.time.LocalDate;
-import java.util.List;
-
-public interface ReservationService {
-    List<ReservationDto> getAllReservationsWithStatus();
-    Reservation getReservationById(Long id);
-    Reservation createReservation(CreateReservationDto dto,String userEmail);
-    Reservation updateReservation(Long id, CreateReservationDto dto,String userEmail);
-    void deleteReservation(Long id);
-    List<Reservation> getAllReservationsByUser(String userEmail);
-    ReservationManagedFrontStaff acceptReservation(Long reservationId, String frontStaffEmail, Long tableNumber);
-
-    List<Reservation> getAllReservationsForToday();
-    List<Reservation> getAllReservationsForDate(LocalDate date);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/RestaurantTableService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/RestaurantTableService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-
-import java.util.List;
-
-public interface RestaurantTableService {
-
-    RestaurantTable findById(Long id);
-    List<RestaurantTable> getAll();
-    RestaurantTable updateTable(Long id, RestaurantTable restaurantTable);
-    void deleteTable(Long id);
-    List<RestaurantTable> getAllBySeatCapacity(Integer seatCapacity);
-    RestaurantTable createTable(RestaurantTable restaurantTable);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/ShiftService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/ShiftService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package finki.db.tasty_tabs.service;
-
-import finki.db.tasty_tabs.entity.Shift;
-import finki.db.tasty_tabs.web.dto.CreateShiftDto;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.List;
-
-public interface ShiftService {
-    List<Shift> getAllShifts();
-    Shift getShiftById(Long id);
-    Shift createShift(CreateShiftDto dto, String username);
-    Shift updateShift(Long id, CreateShiftDto dto, String username);
-    void deleteShift(Long id, String username);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/AnalyticsExtraServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/AnalyticsExtraServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,42 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.repository.AnalyticsReadRepository;
-import finki.db.tasty_tabs.service.AnalyticsExtraService;
-import finki.db.tasty_tabs.web.dto.*;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-@Service
-@RequiredArgsConstructor
-public class AnalyticsExtraServiceImpl implements AnalyticsExtraService {
-
-    private final AnalyticsReadRepository repo;
-
-    @Override public List<ServerPerformanceDto> serverPerformanceLast3Months() {
-        return repo.serverPerformanceLast3Months();
-    }
-    @Override public List<MonthlyRevenueVsLaborDto> monthlyRevenueVsLabor() {
-        return repo.monthlyRevenueVsLabor();
-    }
-    @Override public List<DailyOpsDto> dailyOpsSummary(int daysBack) {
-        return repo.dailyOpsSummary(daysBack <= 0 ? 30 : daysBack);
-    }
-    @Override public List<TopProductDto> topProducts(int daysBack, int limit) {
-        return repo.topProducts(daysBack <= 0 ? 90 : daysBack, limit <= 0 ? 10 : limit);
-    }
-    @Override public List<Map<String, Object>> revenueByShiftPeriodView() {
-        return repo.revenueByShiftPeriodView();
-    }
-    @Override public List<RevenueSplitDto> revenueSplit(LocalDate from, LocalDate to) {
-        if (from == null) from = LocalDate.now().minusDays(30);
-        if (to == null)   to   = LocalDate.now();
-        return repo.revenueSplit(from, to);
-    }
-    @Override public List<ManagerShiftAboveAvgDto> managersShiftsAboveMonthlyAvgCurrentYear() {
-        return repo.managersShiftsAboveMonthlyAvgCurrentYear();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/AnalyticsServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/AnalyticsServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,93 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-
-import finki.db.tasty_tabs.entity.PaymentsDailyChannel;
-import finki.db.tasty_tabs.repository.AnalyticsAdminRepository;
-import finki.db.tasty_tabs.repository.PaymentsDailyChannelRepository;
-import finki.db.tasty_tabs.service.AnalyticsService;
-import finki.db.tasty_tabs.web.dto.AnalyticsByChannelResponse;
-import finki.db.tasty_tabs.web.dto.ChannelTableDto;
-import finki.db.tasty_tabs.web.dto.PaymentsDailyChannelDto;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Service
-public class AnalyticsServiceImpl implements AnalyticsService {
-
-    private final PaymentsDailyChannelRepository mvRepo;
-    private final AnalyticsAdminRepository adminRepo;
-
-    public AnalyticsServiceImpl(PaymentsDailyChannelRepository mvRepo, AnalyticsAdminRepository adminRepo) {
-        this.mvRepo = mvRepo;
-        this.adminRepo = adminRepo;
-    }
-
-    @Override
-    public AnalyticsByChannelResponse getPaymentsDailyChannel(LocalDate from, LocalDate to) {
-        if (from == null) from = LocalDate.now().minusDays(30);
-        if (to == null)   to   = LocalDate.now();
-
-        // pass null channel to fetch ALL channels (JPQL has :channel is null guard)
-        List<PaymentsDailyChannel> rows = mvRepo.findRange(from, to, null);
-
-        // group by channel
-        Map<String, List<PaymentsDailyChannel>> byChannel = rows.stream()
-                .collect(Collectors.groupingBy(PaymentsDailyChannel::getChannel));
-
-        // build per-channel tables
-        List<ChannelTableDto> channels = byChannel.entrySet().stream()
-                .sorted(Map.Entry.comparingByKey()) // ONLINE, TAB, UNKNOWN (alphabetical)
-                .map(e -> {
-                    var data = e.getValue().stream()
-                            .sorted(Comparator.comparing(PaymentsDailyChannel::getDay).thenComparing(PaymentsDailyChannel::getChannel))
-                            .map(r -> new PaymentsDailyChannelDto(
-                                    r.getDay(), r.getChannel(), r.getPaidOrdersCnt(), r.getRevenue(), r.getTipTotal()
-                            ))
-                            .toList();
-
-                    long totalOrders = e.getValue().stream()
-                            .map(PaymentsDailyChannel::getPaidOrdersCnt)
-                            .filter(v -> v != null)
-                            .mapToLong(Long::longValue)
-                            .sum();
-
-                    BigDecimal totalRevenue = e.getValue().stream()
-                            .map(PaymentsDailyChannel::getRevenue)
-                            .filter(v -> v != null)
-                            .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-                    BigDecimal totalTips = e.getValue().stream()
-                            .map(PaymentsDailyChannel::getTipTotal)
-                            .filter(v -> v != null)
-                            .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-                    return new ChannelTableDto(e.getKey(), data, totalOrders, totalRevenue, totalTips);
-                })
-                .toList();
-
-        // grand totals
-        long grandOrders = rows.stream()
-                .map(PaymentsDailyChannel::getPaidOrdersCnt)
-                .filter(v -> v != null)
-                .mapToLong(Long::longValue)
-                .sum();
-
-        BigDecimal grandRevenue = rows.stream()
-                .map(PaymentsDailyChannel::getRevenue)
-                .filter(v -> v != null)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-        BigDecimal grandTips = rows.stream()
-                .map(PaymentsDailyChannel::getTipTotal)
-                .filter(v -> v != null)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-        return new AnalyticsByChannelResponse(from, to, channels, grandOrders, grandRevenue, grandTips);
-    }}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/AssignmentServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/AssignmentServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,130 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.entity.Manager;
-import finki.db.tasty_tabs.entity.Shift;
-import finki.db.tasty_tabs.entity.exceptions.AssignmentNotFoundException;
-import finki.db.tasty_tabs.entity.exceptions.EmployeeNotFoundException;
-import finki.db.tasty_tabs.entity.exceptions.ShiftNotFoundException;
-import finki.db.tasty_tabs.repository.AssignmentRepository;
-import finki.db.tasty_tabs.repository.EmployeeRepository;
-import finki.db.tasty_tabs.repository.ManagerRepository;
-import finki.db.tasty_tabs.repository.ShiftRepository;
-import finki.db.tasty_tabs.service.AssignmentService;
-import finki.db.tasty_tabs.web.dto.CreateAssignmentDto;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Service
-public class AssignmentServiceImpl implements AssignmentService {
-
-    private final AssignmentRepository assignmentRepository;
-    private final ManagerRepository managerRepository;
-    private final EmployeeRepository employeeRepository;
-    private final ShiftRepository shiftRepository;
-
-    public AssignmentServiceImpl(AssignmentRepository assignmentRepository, ManagerRepository managerRepository, EmployeeRepository employeeRepository, ShiftRepository shiftRepository) {
-        this.assignmentRepository = assignmentRepository;
-        this.managerRepository = managerRepository;
-        this.employeeRepository = employeeRepository;
-        this.shiftRepository = shiftRepository;
-    }
-
-    private Manager getManagerByEmail(String email) {
-        return managerRepository.findByEmail(email)
-                .orElseThrow(() -> new AccessDeniedException("Only managers can assign assignments."));
-    }
-
-    @Override
-    public List<Assignment> getAllAssignments() {
-        return assignmentRepository.findAll();
-    }
-
-    @Override
-    public Assignment getAssignmentById(Long id) {
-        return assignmentRepository.findById(id)
-                .orElseThrow(() -> new AssignmentNotFoundException(id));
-    }
-
-    @Override
-    public Assignment createAssignment(CreateAssignmentDto dto, String managerEmail) {
-        Manager manager = getManagerByEmail(managerEmail);
-        Employee employee = employeeRepository.findById(dto.employeeId())
-                .orElseThrow(() -> new EmployeeNotFoundException(dto.employeeId()));
-        Shift shift = shiftRepository.findById(dto.shiftId())
-                .orElseThrow(() -> new ShiftNotFoundException(dto.shiftId()));
-
-        Assignment assignment = new Assignment(
-                dto.clockInTime(),
-                dto.clockOutTime(),
-                manager,
-                employee,
-                shift
-        );
-
-        return assignmentRepository.save(assignment);
-    }
-
-    @Override
-    public Assignment updateAssignment(Long id, CreateAssignmentDto dto, String managerEmail) {
-        Manager manager = getManagerByEmail(managerEmail);
-        Assignment assignment = getAssignmentById(id);
-
-        Employee employee = employeeRepository.findById(dto.employeeId())
-                .orElseThrow(() -> new EmployeeNotFoundException(dto.employeeId()));
-        Shift shift = shiftRepository.findById(dto.shiftId())
-                .orElseThrow(() -> new ShiftNotFoundException(dto.shiftId()));
-
-        assignment.setClockInTime(dto.clockInTime());
-        assignment.setClockOutTime(dto.clockOutTime());
-        assignment.setManager(manager);
-        assignment.setEmployee(employee);
-        assignment.setShift(shift);
-
-        return assignmentRepository.save(assignment);
-    }
-
-    @Override
-    public void deleteAssignment(Long id, String managerEmail) {
-        getManagerByEmail(managerEmail);
-        if (!assignmentRepository.existsById(id)) {
-            throw new AssignmentNotFoundException(id);
-        }
-        assignmentRepository.deleteById(id);
-    }
-    @Override
-    public Assignment clockInShift(Long assignmentId, String employeeEmail, LocalDateTime clockInTime) {
-        Assignment assignment = assignmentRepository.findById(assignmentId)
-                .orElseThrow(() -> new AssignmentNotFoundException( assignmentId));
-
-        // Check if the logged-in employee is assigned to this assignment
-        if (!assignment.getEmployee().getEmail().equals(employeeEmail)) {
-            throw new AccessDeniedException("You can only clock in your own shift.");
-        }
-
-        assignment.setClockInTime(clockInTime);
-        return assignmentRepository.save(assignment);
-    }
-
-    @Override
-    public Assignment clockOutShift(Long assignmentId, String employeeEmail, LocalDateTime clockOutTime) {
-        Assignment assignment = assignmentRepository.findById(assignmentId)
-                .orElseThrow(() -> new AssignmentNotFoundException(assignmentId));
-
-        if (!assignment.getEmployee().getEmail().equals(employeeEmail)) {
-            throw new AccessDeniedException("You can only clock out your own shift.");
-        }
-
-        if (assignment.getClockInTime() == null) {
-            throw new IllegalStateException("Cannot clock out without clocking in first.");
-        }
-
-        assignment.setClockOutTime(clockOutTime);
-        return assignmentRepository.save(assignment);
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/AuthServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/AuthServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,77 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.Customer;
-import finki.db.tasty_tabs.entity.User;
-import finki.db.tasty_tabs.repository.UserRepository;
-import finki.db.tasty_tabs.service.AuthService;
-import finki.db.tasty_tabs.utils.JwtProvider;
-import finki.db.tasty_tabs.web.dto.AuthDto;
-import finki.db.tasty_tabs.web.dto.request.RegisterRequest;
-import finki.db.tasty_tabs.web.dto.UserDto;
-import jakarta.transaction.Transactional;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-@Service
-public class AuthServiceImpl implements AuthService {
-    private final UserRepository userRepository;
-    private final JwtProvider jwtProvider;
-    private final AuthenticationManager authenticationManager;
-    private final PasswordEncoder passwordEncoder;
-
-    public AuthServiceImpl(UserRepository userRepository, JwtProvider jwtProvider, AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder) {
-        this.userRepository = userRepository;
-        this.jwtProvider = jwtProvider;
-        this.authenticationManager = authenticationManager;
-        this.passwordEncoder = passwordEncoder;
-    }
-
-    @Override
-    public AuthDto authenticate(String email, String password) {
-        Authentication authentication = authenticationManager.authenticate(
-                new UsernamePasswordAuthenticationToken(email, password)
-        );
-
-        User user = userRepository.findByEmail(email)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        String token = jwtProvider.generateToken(user.getEmail());
-
-        return new AuthDto(
-                token,
-                UserDto.from(user)
-        );
-    }
-
-
-    @Override
-    @Transactional
-    public AuthDto register(RegisterRequest request) {
-        User user = userRepository.findByEmail(request.getEmail()).orElse(null);
-        if (user != null){
-            throw new RuntimeException("User with this email already exists");
-        }
-
-        User newUser = new Customer();
-        newUser.setEmail(request.getEmail());
-        newUser.setPassword(passwordEncoder.encode(request.getPassword()));
-        userRepository.save(newUser);
-
-        String token = jwtProvider.generateToken(request.getEmail());
-
-        return new AuthDto(token, UserDto.from(newUser));
-    }
-
-    @Override
-    public UserDto getAuthenticatedUser() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-
-        return UserDto.from(userRepository.findByEmail(authentication.getName())
-                .orElseThrow(() -> new RuntimeException("User not found")));
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/CategoryServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/CategoryServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,58 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.Category;
-import finki.db.tasty_tabs.entity.exceptions.CategoryNotFoundException;
-import finki.db.tasty_tabs.repository.CategoryRepository;
-import finki.db.tasty_tabs.service.CategoryService;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Optional;
-
-@Service
-public class CategoryServiceImpl implements CategoryService {
-
-    private final CategoryRepository categoryRepository;
-
-    public CategoryServiceImpl(CategoryRepository categoryRepository) {
-        this.categoryRepository = categoryRepository;
-    }
-
-    @Override
-    public Category findById(Long id) {
-        return categoryRepository.findById(id).orElseThrow(CategoryNotFoundException::new);
-    }
-
-    @Override
-    public List<Category> getAllCategories() {
-        return categoryRepository.findAll();
-    }
-
-    @Override
-    public Category updateCategory(Long id, Category category) {
-        return categoryRepository.findById(id).map(existingCategory -> {
-            if (category.getName() != null) {
-                existingCategory.setName(category.getName());
-            }
-            if (category.getIsAvailable() != null) {
-                existingCategory.setIsAvailable(category.getIsAvailable());
-            }
-            return categoryRepository.save(existingCategory);
-        }).orElseThrow(CategoryNotFoundException::new);
-    }
-
-    @Override
-    public void deleteCategory(Long id) {
-        categoryRepository.deleteById(id);
-    }
-
-    @Override
-    public Category getCategoryByName(String name) {
-        return categoryRepository.findByName(name).orElseThrow(CategoryNotFoundException::new);
-    }
-
-    @Override
-    public Category createCategory(Category category) {
-        return categoryRepository.save(category);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/EmployeeServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/EmployeeServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,119 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.*;
-import finki.db.tasty_tabs.repository.*;
-import finki.db.tasty_tabs.service.EmployeeService;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.CreateEmployeeRequest;
-import finki.db.tasty_tabs.web.dto.EmployeeDto;
-import jakarta.persistence.EntityNotFoundException;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.Optional;
-
-@Service
-@Transactional
-class EmployeeServiceImpl implements EmployeeService { // New Service Implementation
-
-    private final UserRepository userRepository;
-    private final ManagerRepository managerRepository;
-    private final FrontStaffRepository frontStaffRepository;
-    private final BackStaffRepository backStaffRepository;
-    private final StaffRoleRepository staffRoleRepository;
-    private final PasswordEncoder passwordEncoder;
-    private final EmployeeRepository employeeRepository;
-    private final AssignmentRepository assignmentRepository;
-
-    EmployeeServiceImpl(UserRepository userRepository, ManagerRepository managerRepository, FrontStaffRepository frontStaffRepository, BackStaffRepository backStaffRepository, StaffRoleRepository staffRoleRepository, PasswordEncoder passwordEncoder, EmployeeRepository employeeRepository, AssignmentRepository assignmentRepository) {
-        this.userRepository = userRepository;
-        this.managerRepository = managerRepository;
-        this.frontStaffRepository = frontStaffRepository;
-        this.backStaffRepository = backStaffRepository;
-        this.staffRoleRepository = staffRoleRepository;
-        this.passwordEncoder = passwordEncoder;
-        this.employeeRepository = employeeRepository;
-        this.assignmentRepository = assignmentRepository;
-    }
-
-    @Override
-    public List<EmployeeDto> getAllEmployees() {
-        List<Employee> employees = employeeRepository.findAll();
-
-        return employees.stream()
-                .map(EmployeeDto::from)
-                .toList();
-    }
-
-    @Override
-    public AssignmentDto getNextShiftForEmployee(Long employeeId) {
-        Assignment assignment = assignmentRepository.findFirstByEmployee_IdAndClockOutTimeNullOrderByShiftStartAsc(employeeId).orElse(null);
-
-        if (assignment == null) {
-            throw new EntityNotFoundException("No upcoming shifts found for employee with id: " + employeeId);
-        }
-
-        return AssignmentDto.fromAssignment(assignment);
-    }
-
-    @Override
-    public boolean isOnActiveShift(Long employeeId) {
-        Optional<Assignment> assignment = assignmentRepository.findFirstByEmployee_IdAndClockInTimeNotNullAndClockOutTimeNull(employeeId);
-        return assignment.isPresent();
-    }
-
-    @Override
-    @Transactional
-    public Employee createEmployee(CreateEmployeeRequest request) {
-        // In a real app, you'd check if email is unique and hash the password
-        if (userRepository.existsByEmail(request.email())) {
-             throw new IllegalArgumentException("Employee with email " + request.email() + " already exists.");
-        }
-
-        Employee employee;
-
-        switch (request.employeeType()) {
-            case MANAGER:
-                Manager manager = new Manager();
-                setCommonEmployeeFields(manager, request);
-
-                employee = manager;
-                break;
-            case FRONT_STAFF:
-                FrontStaff frontStaff = new FrontStaff();
-                setCommonEmployeeFields(frontStaff, request);
-                StaffRole frontStaffRole = staffRoleRepository.findById(request.staffRoleId())
-                        .orElseThrow(() -> new EntityNotFoundException("StaffRole not found with id: " + request.staffRoleId()));
-                frontStaff.setStaffRole(frontStaffRole);
-                frontStaff.setTipPercent(request.tipPercent());
-
-                employee = frontStaff;
-                break;
-            case BACK_STAFF:
-                BackStaff backStaff = new BackStaff();
-                setCommonEmployeeFields(backStaff, request);
-                StaffRole backStaffRole = staffRoleRepository.findById(request.staffRoleId())
-                        .orElseThrow(() -> new EntityNotFoundException("StaffRole not found with id: " + request.staffRoleId()));
-                backStaff.setStaffRole(backStaffRole);
-
-                employee = backStaff;
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid employee type: " + request.email());
-        }
-
-        return userRepository.save(employee);
-    }
-
-    private void setCommonEmployeeFields(Employee employee, CreateEmployeeRequest request) {
-        employee.setEmail(request.email());
-        employee.setPassword(passwordEncoder.encode(request.password()));
-        employee.setStreet(request.street());
-        employee.setCity(request.city());
-        employee.setPhoneNumber(request.phoneNumber());
-        employee.setNetSalary(request.netSalary());
-        employee.setGrossSalary(request.grossSalary());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/OrderServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/OrderServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,309 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.aspect.annotation.CheckOnDuty;
-import finki.db.tasty_tabs.entity.*;
-import finki.db.tasty_tabs.entity.exceptions.*;
-import finki.db.tasty_tabs.repository.*;
-import finki.db.tasty_tabs.service.OrderService;
-import finki.db.tasty_tabs.web.dto.CreateOrderDto;
-import finki.db.tasty_tabs.web.dto.CreateOrderItemDto;
-import jakarta.transaction.Transactional;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class OrderServiceImpl implements OrderService {
-
-    private final OrderRepository orderRepository;
-    private final OrderItemRepository orderItemRepository;
-    private final ProductRepository productRepository;
-    private final RestaurantTableRepository tableRepository;
-    private final UserRepository userRepository;
-    private final TabOrderRepository tabOrderRepository;
-    private final OnlineOrderRepository onlineOrderRepository;
-    private final FrontStaffRepository frontStaffRepository;
-    private final CustomerRepository customerRepository;
-
-    @Override
-    public List<Order> findAll() {
-        return orderRepository.findAll();
-    }
-
-    @Override
-    public Order findById(Long id) {
-        return orderRepository.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
-    }
-
-    @Override
-    @CheckOnDuty
-    public Order updateOrder(Long id, CreateOrderDto dto) {
-        Order existingOrder = findById(id);
-
-        existingOrder.setStatus(dto.status());
-
-        existingOrder.getOrderItems().clear();
-        List<OrderItem> newOrderItems = dto.orderItems().stream().map(itemDto -> {
-            OrderItem item = new OrderItem();
-            item.setOrder(existingOrder);
-            item.setQuantity(itemDto.quantity());
-            item.setPrice(itemDto.price());
-            item.setIsProcessed(itemDto.isProcessed());
-            item.setTimestamp(LocalDateTime.now());
-            Product product = productRepository.findById(itemDto.productId())
-                    .orElseThrow(() -> new ProductNotFoundException(itemDto.productId()));
-            item.setProduct(product);
-            return item;
-        }).collect(Collectors.toList());
-
-        existingOrder.setOrderItems(newOrderItems);
-
-        return orderRepository.save(existingOrder);
-    }
-
-    @Override
-    public void deleteOrder(Long id) {
-        orderRepository.deleteById(id);
-    }
-
-    @Override
-    public double calculateTotalPrice(Long orderId) {
-        Order order = findById(orderId);
-        return order.getOrderItems().stream()
-                .mapToDouble(item -> item.getQuantity() * item.getPrice())
-                .sum();
-    }
-
-    @Override
-    @CheckOnDuty
-    public void updateOrderStatus(Long orderId, String newStatus) {
-        Order order = findById(orderId);
-        order.setStatus(newStatus);
-        orderRepository.save(order);
-    }
-
-    // Methods for Order Items
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public OrderItem addItemToOrder(Long orderId, CreateOrderItemDto itemDto) {
-        Order order = findById(orderId);
-        OrderItem orderItem = new OrderItem();
-        orderItem.setOrder(order);
-        orderItem.setQuantity(itemDto.quantity());
-        orderItem.setPrice(itemDto.price());
-        orderItem.setIsProcessed(itemDto.isProcessed());
-        orderItem.setTimestamp(LocalDateTime.now());
-        Product product = productRepository.findById(itemDto.productId())
-                .orElseThrow(() -> new ProductNotFoundException(itemDto.productId()));
-        orderItem.setProduct(product);
-        return orderItemRepository.save(orderItem);
-    }
-
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public void decreaseOrderItemQuantity(Long orderItemId) {
-        OrderItem orderItem = orderItemRepository.findById(orderItemId)
-                .orElseThrow(OrderItemNotFoundException::new);
-        if (orderItem.getQuantity() > 1) {
-            orderItem.setQuantity(orderItem.getQuantity() - 1);
-            orderItemRepository.save(orderItem);
-        } else {
-            orderItemRepository.delete(orderItem);
-        }
-    }
-
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public OrderItem updateOrderItem(Long orderItemId, CreateOrderItemDto itemDto) {
-        OrderItem orderItem = orderItemRepository.findById(orderItemId)
-                .orElseThrow(OrderItemNotFoundException::new);
-        orderItem.setQuantity(itemDto.quantity());
-        orderItem.setPrice(itemDto.price());
-        orderItem.setIsProcessed(itemDto.isProcessed());
-        Product product = productRepository.findById(itemDto.productId())
-                .orElseThrow(() -> new ProductNotFoundException(itemDto.productId()));
-        orderItem.setProduct(product);
-        return orderItemRepository.save(orderItem);
-    }
-
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public void deleteOrderItem(Long orderItemId) {
-        orderItemRepository.deleteById(orderItemId);
-    }
-
-    @Override
-    @Transactional
-    public OrderItem processOrderItem(Long orderItemId) {
-        OrderItem orderItem = orderItemRepository.findById(orderItemId)
-                .orElseThrow(OrderItemNotFoundException::new);
-        orderItem.setIsProcessed(true);
-        return orderItemRepository.save(orderItem);
-    }
-
-    // Specific OnlineOrder methods
-    @Override
-    @Transactional
-    public OnlineOrder createOnlineOrder(CreateOrderDto dto, String userEmail) {
-        User user = userRepository.findByEmail(userEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + userEmail + " not found."));
-        if (!(user instanceof Customer)) {
-            throw new SecurityException("User is not authorized to create online orders.");
-        }
-        OnlineOrder onlineOrder = new OnlineOrder();
-        onlineOrder.setCustomer((Customer) user);
-        onlineOrder.setDeliveryAddress(dto.deliveryAddress());
-        onlineOrder.setTimestamp(LocalDateTime.now());
-        onlineOrder.setStatus(dto.status());
-        if (dto.orderItems() != null && !dto.orderItems().isEmpty()) {
-            List<OrderItem> orderItems = dto.orderItems().stream().map(itemDto -> {
-                OrderItem item = new OrderItem();
-                item.setOrder(onlineOrder);
-                item.setQuantity(itemDto.quantity());
-                item.setPrice(itemDto.price());
-                item.setIsProcessed(itemDto.isProcessed());
-                item.setTimestamp(LocalDateTime.now());
-                Product product = productRepository.findById(itemDto.productId())
-                        .orElseThrow(() -> new ProductNotFoundException(itemDto.productId()));
-                item.setProduct(product);
-                return item;
-            }).collect(Collectors.toList());
-            onlineOrder.setOrderItems(orderItems);
-        }
-        return onlineOrderRepository.save(onlineOrder);
-    }
-
-    @Override
-    public OnlineOrder findOnlineOrderById(Long id) {
-        return onlineOrderRepository.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
-    }
-
-    @Override
-    public List<OnlineOrder> findAllOnlineOrders() {
-        return onlineOrderRepository.findAll();
-    }
-
-    @Override
-    public List<OnlineOrder> findOnlineOrdersByCustomer(Long customerId) {
-        return onlineOrderRepository.findAllByCustomer_Id(customerId);
-    }
-
-    // Specific TabOrder methods
-    // Specific TabOrder methods
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public TabOrder createTabOrder(CreateOrderDto dto, String userEmail) {
-        log.debug("User {} creating a tab order for table {}", userEmail, dto.tableNumber());
-        User user = userRepository.findByEmail(userEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + userEmail + " not found."));
-        if (!(user instanceof Employee)) { // Changed to Employee since any employee can create an order now
-            throw new SecurityException("User is not authorized to create tab orders.");
-        }
-        TabOrder tabOrder = new TabOrder();
-        RestaurantTable table = tableRepository.findById(dto.tableNumber())
-                .orElseThrow(() -> new TableNotFoundException(dto.tableNumber()));
-        tabOrder.setRestaurantTable(table);
-        tabOrder.setTimestamp(LocalDateTime.now());
-        tabOrder.setStatus(dto.status());
-        tabOrder.setEmployee((Employee) user); // Assign the employee who created the order
-
-        if (dto.orderItems() != null && !dto.orderItems().isEmpty()) {
-            log.debug("OrderItems is not empty, processing items...");
-            List<OrderItem> orderItems = dto.orderItems().stream().map(itemDto -> {
-                OrderItem item = new OrderItem();
-                item.setOrder(tabOrder);
-                item.setQuantity(itemDto.quantity());
-                item.setPrice(itemDto.price());
-                item.setIsProcessed(itemDto.isProcessed());
-                item.setTimestamp(LocalDateTime.now());
-                Product product = productRepository.findById(itemDto.productId())
-                        .orElseThrow(() -> new ProductNotFoundException(itemDto.productId()));
-                item.setProduct(product);
-                return item;
-            }).collect(Collectors.toList());
-            tabOrder.setOrderItems(orderItems);
-        }
-        return tabOrderRepository.save(tabOrder);
-    }
-
-    @Override
-    public TabOrder findTabOrderById(Long id) {
-        return tabOrderRepository.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
-    }
-
-    @Override
-    public List<TabOrder> findAllTabOrders() {
-        return tabOrderRepository.findAll();
-    }
-
-    @Override
-    public List<TabOrder> findTabOrdersByTableAndDate(Integer tableNumber, LocalDate date) {
-        LocalDateTime startOfDay = date.atStartOfDay();
-        LocalDateTime endOfDay = date.atTime(23, 59, 59);
-        return tabOrderRepository.findByRestaurantTable_TableNumberAndTimestampBetween(tableNumber, startOfDay, endOfDay);
-    }
-
-    @Override
-    public List<TabOrder> findTabOrdersByStaff(Long frontStaffId) {
-        return tabOrderRepository.findAllByOrder_Employee_Id(frontStaffId);
-    }
-
-
-
-    // General methods for all order types
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public Order cancelOrder(Long orderId) {
-        Order order = findById(orderId);
-        order.setStatus("CANCELED");
-        return orderRepository.save(order);
-    }
-
-    @Override
-    public List<Order> findOpenOrders() {
-
-        // Query the OnlineOrderRepository for open orders
-        List<OnlineOrder> onlineOrders = onlineOrderRepository.findAllByStatusIn(List.of("PENDING", "CONFIRMED"));
-
-        // Query the TabOrderRepository for open orders
-        List<TabOrder> tabOrders = tabOrderRepository.findAllByStatusIn(List.of("PENDING", "CONFIRMED"));
-
-        // Combine the lists into a single List<Order>
-        List<Order> combinedOrders = new java.util.ArrayList<>();
-        combinedOrders.addAll(onlineOrders);
-        combinedOrders.addAll(tabOrders);
-
-        return combinedOrders;
-    }
-
-    @Override
-    public List<Order> findClosedOrders() {
-
-        // Query the OnlineOrderRepository for open orders
-        List<OnlineOrder> onlineOrders = onlineOrderRepository.findAllByStatusIn(List.of("CLOSED"));
-
-        // Query the TabOrderRepository for open orders
-        List<TabOrder> tabOrders = tabOrderRepository.findAllByStatus("CLOSED");
-
-        // Combine the lists into a single List<Order>
-        List<Order> combinedOrders = new java.util.ArrayList<>();
-        combinedOrders.addAll(onlineOrders);
-        combinedOrders.addAll(tabOrders);
-
-        return combinedOrders;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/PaymentServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/PaymentServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,85 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-
-import finki.db.tasty_tabs.aspect.annotation.CheckOnDuty;
-import finki.db.tasty_tabs.entity.Order;
-import finki.db.tasty_tabs.entity.Payment;
-import finki.db.tasty_tabs.entity.exceptions.OrderNotFoundException;
-import finki.db.tasty_tabs.entity.exceptions.PaymentNotFoundException;
-import finki.db.tasty_tabs.repository.OrderRepository;
-import finki.db.tasty_tabs.repository.PaymentRepository;
-import finki.db.tasty_tabs.service.PaymentService;
-import finki.db.tasty_tabs.service.viewRefreshers.MvRefresher;
-import finki.db.tasty_tabs.web.dto.CreatePaymentDto;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import jakarta.transaction.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class PaymentServiceImpl implements PaymentService {
-
-    private final PaymentRepository paymentRepository;
-    private final OrderRepository orderRepository;
-    private final MvRefresher mvRefresher;
-
-
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public Payment createPayment(CreatePaymentDto dto) {
-        log.info("Creating payment for orderId: {}", dto.orderId());
-        Order order = orderRepository.findById(dto.orderId())
-                .orElseThrow(() -> new OrderNotFoundException(dto.orderId()));
-
-        Payment payment = new Payment();
-        payment.setAmount(dto.amount());
-        payment.setTipAmount(dto.tipAmount());
-        payment.setPaymentType(dto.paymentType());
-        payment.setTimestamp(LocalDateTime.now()); // ensure mapped to created_at column
-        payment.setOrder(order);
-
-        Payment saved = paymentRepository.save(payment);
-
-        // Schedule MV refresh after the transaction commits
-        mvRefresher.refreshPaymentsMvAfterCommit();
-
-        return saved;
-    }
-
-    @Override
-    public Payment findPaymentById(Long id) {
-        return paymentRepository.findById(id)
-                .orElseThrow(() -> new PaymentNotFoundException(id));
-    }
-
-    @Override
-    public Payment findPaymentByOrderId(Long orderId) {
-        return paymentRepository.findByOrderId(orderId)
-                .orElseThrow(() -> new PaymentNotFoundException(orderId));
-    }
-
-    @Override
-    public List<Payment> findAllPayments() {
-        return paymentRepository.findAll();
-    }
-
-    @Override
-    @Transactional
-    @CheckOnDuty
-    public Payment updatePayment(Long id, CreatePaymentDto dto) {
-        Payment existingPayment = findPaymentById(id);
-
-        existingPayment.setAmount(dto.amount());
-        existingPayment.setTipAmount(dto.tipAmount());
-        existingPayment.setPaymentType(dto.paymentType());
-
-        return paymentRepository.save(existingPayment);
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/ProductServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/ProductServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,132 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-
-import finki.db.tasty_tabs.entity.Inventory;
-import finki.db.tasty_tabs.entity.Product;
-import finki.db.tasty_tabs.entity.exceptions.ProductNotFoundException;
-import finki.db.tasty_tabs.repository.InventoryRepository;
-import finki.db.tasty_tabs.repository.ProductRepository;
-import finki.db.tasty_tabs.service.CategoryService;
-import finki.db.tasty_tabs.service.ProductService;
-import finki.db.tasty_tabs.web.dto.CreateProductDto;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Optional;
-
-@Service
-public class ProductServiceImpl implements ProductService {
-
-    private final ProductRepository productRepository;
-    private final CategoryService categoryService;
-    private final InventoryRepository inventoryRepository;
-
-
-    public ProductServiceImpl(ProductRepository productRepository, CategoryService categoryService,InventoryRepository inventoryRepository) {
-        this.productRepository = productRepository;
-        this.categoryService = categoryService;
-        this.inventoryRepository=inventoryRepository;
-    }
-
-    @Override
-    public Product findById(Long id) {
-        return productRepository.findById(id)
-                .orElseThrow(() -> new ProductNotFoundException(id));
-    }
-
-    @Override
-    public List<Product> getAllProducts() {
-        return productRepository.findAll();
-    }
-
-    @Override
-    public Product updateProduct(Long id, CreateProductDto dto) {
-        Product existingProduct = productRepository.findById(id)
-                .orElseThrow(() -> new ProductNotFoundException(id));
-
-        // Update product fields
-        if (dto.name() != null) {
-            existingProduct.setName(dto.name());
-        }
-        if (dto.price() != null) {
-            existingProduct.setPrice(dto.price());
-        }
-        if (dto.taxClass() != null) {
-            existingProduct.setTaxClass(dto.taxClass());
-        }
-        if (dto.categoryId() != null) {
-            existingProduct.setCategory(categoryService.findById(dto.categoryId()));
-        }
-        if (dto.description() != null) {
-            existingProduct.setDescription(dto.description());
-        }
-
-        // Manage inventory
-        if (Boolean.TRUE.equals(dto.manageInventory())) {
-            // ако производот претходно не менаџирал inventory -> креирај нов
-            if (Boolean.FALSE.equals(existingProduct.getManageInventory())) {
-                Inventory inventory = new Inventory(existingProduct, dto.quantity(), dto.restockLevel());
-                inventoryRepository.save(inventory);
-            } else {
-                // ако веќе постои -> update
-                Inventory inventory = inventoryRepository.findById(id)
-                        .orElseThrow(() -> new RuntimeException("Inventory not found for product " + id));
-                if (dto.quantity() != null) {
-                    inventory.setQuantity(dto.quantity());
-                }
-                if (dto.restockLevel() != null) {
-                    inventory.setRestockLevel(dto.restockLevel());
-                }
-                inventoryRepository.save(inventory);
-            }
-        } else if (Boolean.FALSE.equals(dto.manageInventory())) {
-            // ако од TRUE се префрла на FALSE -> бриши го inventory-то
-            inventoryRepository.findById(id).ifPresent(inventoryRepository::delete);
-        }
-
-        // на крај секогаш го сетирај manageInventory флагот
-        if (dto.manageInventory() != null) {
-            existingProduct.setManageInventory(dto.manageInventory());
-        }
-
-        return productRepository.save(existingProduct);
-    }
-
-    @Override
-    public void deleteProduct(Long id) {
-        productRepository.deleteById(id);
-    }
-
-    @Override
-    public List<Product> getProductsByName(String name) {
-
-        return productRepository.findAllByName(name);
-    }
-
-    @Override
-    public Product createProduct(CreateProductDto dto) {
-        Product productTmp=new Product();
-        if (dto.name() != null) {
-            productTmp.setName(dto.name());
-        }
-        if (dto.price() != null) {
-            productTmp.setPrice(dto.price());
-        }
-        if(dto.taxClass()!=null){
-            productTmp.setTaxClass(dto.taxClass());
-        }
-
-        productTmp.setCategory(categoryService.findById(dto.categoryId()));
-        productTmp.setDescription(dto.description());
-
-        if(dto.manageInventory()!=null){
-            productTmp.setManageInventory(dto.manageInventory());
-        }
-        Product product=productRepository.save(productTmp);
-        if(product.getManageInventory()==Boolean.TRUE){
-            Inventory inventory = new Inventory(product, dto.quantity(), dto.restockLevel());
-            inventoryRepository.save(inventory);
-        }
-        return product;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/ReservationServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/ReservationServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,162 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.*;
-import finki.db.tasty_tabs.entity.composite_keys.ReservationManagedFrontStaffId;
-import finki.db.tasty_tabs.entity.exceptions.ReservationNotFoundException;
-import finki.db.tasty_tabs.entity.exceptions.TableNotFoundException;
-import finki.db.tasty_tabs.repository.*;
-import finki.db.tasty_tabs.service.ReservationService;
-import finki.db.tasty_tabs.web.dto.CreateReservationDto;
-import finki.db.tasty_tabs.web.dto.ReservationDto;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Service
-public class ReservationServiceImpl implements ReservationService {
-
-    private final ReservationRepository reservationRepository;
-    private final UserRepository userRepository;
-    private final FrontStaffRepository frontStaffRepository;
-    private final RestaurantTableRepository restaurantTableRepository;
-    private final ReservationManagedFrontStaffRepository reservationManagedFrontStaffRepository;
-
-    public ReservationServiceImpl(ReservationRepository reservationRepository, UserRepository userRepository, FrontStaffRepository frontStaffRepository, RestaurantTableRepository restaurantTableRepository, ReservationManagedFrontStaffRepository reservationManagedFrontStaffRepository) {
-        this.reservationRepository = reservationRepository;
-        this.userRepository = userRepository;
-        this.frontStaffRepository = frontStaffRepository;
-        this.restaurantTableRepository = restaurantTableRepository;
-        this.reservationManagedFrontStaffRepository = reservationManagedFrontStaffRepository;
-    }
-
-    @Override
-    public List<ReservationDto> getAllReservationsWithStatus() {
-        return reservationRepository.findAll().stream()
-                .map(r -> {
-                    // Fetch assignment (if any)
-                    var opt = reservationManagedFrontStaffRepository.findFirstByReservation_Id(r.getId());
-                    boolean accepted = opt.isPresent();
-
-                    Long tableNumber = opt.map(m -> {
-                        // Assuming RestaurantTable.tableNumber is an Integer/Long
-                        var t = m.getRestaurantTable();
-                        return (t == null) ? null : (t.getTableNumber() == null ? null : t.getTableNumber().longValue());
-                    }).orElse(null);
-
-                    String frontStaffName = opt.map(m -> {
-                        // Safest fallback: use the front-staff user's email
-                        var fs = m.getFrontStaff();
-                        return (fs != null && fs.getEmail() != null) ? fs.getEmail() : "Front Staff";
-                        // If you *do* store names in your model, replace with fs.getFullName() (or first/last)
-                    }).orElse(null);
-
-                    return ReservationDto.from(r, accepted, tableNumber, frontStaffName);
-                })
-                .toList();
-    }
-    @Override
-    public Reservation getReservationById(Long id) {
-        return reservationRepository.findById(id)
-                .orElseThrow(() -> new ReservationNotFoundException(id));
-    }
-
-    @Override
-    public Reservation createReservation(CreateReservationDto dto, String userEmail) {
-        User user = userRepository.findByEmail(userEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + userEmail + " not found."));
-
-        Reservation reservation = new Reservation();
-        reservation.setStayLength(dto.stayLength());
-        reservation.setDatetime(dto.datetime());
-        reservation.setNumberOfPeople(dto.numberOfPeople());
-        reservation.setUser(user);
-        reservation.setCreationTimestamp(LocalDateTime.now());
-
-        return reservationRepository.save(reservation);
-    }
-
-    @Override
-    public Reservation updateReservation(Long id, CreateReservationDto dto, String userEmail) {
-        Reservation existing = getReservationById(id);
-
-        User user = userRepository.findByEmail(userEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + userEmail + " not found."));
-
-        // Optionally, add a check if the logged-in user is allowed to update this reservation
-        if (!existing.getUser().getId().equals(user.getId())) {
-            throw new SecurityException("You are not authorized to update this reservation.");
-        }
-
-        existing.setStayLength(dto.stayLength());
-        existing.setDatetime(dto.datetime());
-        existing.setNumberOfPeople(dto.numberOfPeople());
-        existing.setUser(user);
-
-        return reservationRepository.save(existing);
-    }
-
-    @Override
-    public void deleteReservation(Long id) {
-        reservationRepository.deleteById(id);
-    }
-
-    @Override
-    public List<Reservation> getAllReservationsByUser(String userEmail) {
-        User user = userRepository.findByEmail(userEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + userEmail + " not found."));
-        return reservationRepository.findAllByUser(user);
-    }
-
-    @Override
-    public ReservationManagedFrontStaff acceptReservation(Long reservationId, String frontStaffEmail, Long tableNumber) {
-        User user = userRepository.findByEmail(frontStaffEmail)
-                .orElseThrow(() -> new UsernameNotFoundException("User with email " + frontStaffEmail + " not found."));
-
-        if (!(user instanceof FrontStaff)) {
-            throw new SecurityException("User is not authorized to accept reservations as they are not a FrontStaff member.");
-        }
-        FrontStaff frontStaff = (FrontStaff) user;
-        // 2. Fetch all other required entities
-        Reservation reservation = reservationRepository.findById(reservationId)
-                .orElseThrow(() -> new ReservationNotFoundException(reservationId));
-
-        RestaurantTable table = restaurantTableRepository.findById(tableNumber)
-                .orElseThrow(() -> new TableNotFoundException(tableNumber));
-
-        // 3. Create the new ReservationManagedFrontStaff entity
-        ReservationManagedFrontStaffId id = new ReservationManagedFrontStaffId(
-                reservation.getId(),
-                frontStaff.getId(),
-                table.getTableNumber()
-        );
-
-        ReservationManagedFrontStaff managedReservation = new ReservationManagedFrontStaff();
-        managedReservation.setReservation(reservation);
-        managedReservation.setFrontStaff(frontStaff);
-        managedReservation.setRestaurantTable(table);
-        managedReservation.setId(id);
-
-        // 4. Save the new entity to the database
-        return reservationManagedFrontStaffRepository.save(managedReservation);
-    }
-    @Override
-    public List<Reservation> getAllReservationsForToday() {
-        LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
-        LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59);
-
-        return reservationRepository.findAllByDatetimeBetween(startOfDay, endOfDay);
-    }
-
-    @Override
-    public List<Reservation> getAllReservationsForDate(LocalDate date) {
-        LocalDateTime startOfDay = date.atStartOfDay();
-        LocalDateTime endOfDay = date.atTime(23, 59, 59);
-
-        return reservationRepository.findAllByDatetimeBetween(startOfDay, endOfDay);
-    }
-
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/RestaurantTableServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/RestaurantTableServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,65 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-import finki.db.tasty_tabs.entity.exceptions.TableNotFoundException;
-import finki.db.tasty_tabs.entity.exceptions.TableNumberAlreadyExistsException;
-import finki.db.tasty_tabs.repository.RestaurantTableRepository;
-import finki.db.tasty_tabs.service.RestaurantTableService;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-public class RestaurantTableServiceImpl implements RestaurantTableService {
-
-    private final RestaurantTableRepository tableRepository;
-
-    public RestaurantTableServiceImpl(RestaurantTableRepository tableRepository) {
-        this.tableRepository = tableRepository;
-    }
-
-    @Override
-    public RestaurantTable findById(Long id) {
-        return tableRepository.findById(id).orElseThrow(()->new TableNotFoundException(id));
-    }
-
-    @Override
-    public List<RestaurantTable> getAll() {
-        return tableRepository.findAll();
-    }
-
-    @Override
-    public RestaurantTable updateTable(Long id, RestaurantTable restaurantTable) {
-        if(tableRepository.findById(restaurantTable.getTableNumber()).isPresent() && id!=restaurantTable.getTableNumber()){
-            throw new TableNumberAlreadyExistsException(restaurantTable.getTableNumber());
-        }
-        return tableRepository.findById(id).map(existingTable -> {
-            if (restaurantTable.getTableNumber() != null) {
-                existingTable.setTableNumber(restaurantTable.getTableNumber());
-            }
-            if (restaurantTable.getSeatCapacity() != null) {
-                existingTable.setSeatCapacity(restaurantTable.getSeatCapacity());
-            }
-            return tableRepository.save(existingTable);
-        }).orElseThrow(()->new TableNotFoundException(id));
-    }
-
-    @Override
-    public void deleteTable(Long id) {
-        tableRepository.deleteById(id);
-    }
-
-
-    @Override
-    public List<RestaurantTable> getAllBySeatCapacity(Integer seatCapacity) {
-        return tableRepository.findAllBySeatCapacity(seatCapacity);
-    }
-
-    @Override
-    public RestaurantTable createTable(RestaurantTable restaurantTable) {
-        if(tableRepository.findById(restaurantTable.getTableNumber()).isPresent()){
-            throw new TableNumberAlreadyExistsException(restaurantTable.getTableNumber());
-        }
-        return tableRepository.save(restaurantTable);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/impl/ShiftServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/ShiftServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,79 +1,0 @@
-package finki.db.tasty_tabs.service.impl;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.entity.Manager;
-import finki.db.tasty_tabs.entity.Shift;
-import finki.db.tasty_tabs.entity.exceptions.ShiftNotFoundException;
-import finki.db.tasty_tabs.repository.AssignmentRepository;
-import finki.db.tasty_tabs.repository.EmployeeRepository;
-import finki.db.tasty_tabs.repository.ManagerRepository;
-import finki.db.tasty_tabs.repository.ShiftRepository;
-import finki.db.tasty_tabs.service.ShiftService;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.ClockInRequest;
-import finki.db.tasty_tabs.web.dto.CreateShiftDto;
-import finki.db.tasty_tabs.web.dto.ShiftDto;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import jakarta.persistence.EntityNotFoundException;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Service
-public class ShiftServiceImpl implements ShiftService{
-    private final ShiftRepository shiftRepository;
-    private final ManagerRepository managerRepository;
-
-    public ShiftServiceImpl(ShiftRepository shiftRepository, ManagerRepository managerRepository) {
-        this.shiftRepository = shiftRepository;
-        this.managerRepository = managerRepository;
-    }
-
-    private Manager getManagerByUsername(String username) {
-        return managerRepository.findByEmail(username)
-                .orElseThrow(() -> new AccessDeniedException("Only managers can assign shifts."));
-    }
-
-    @Override
-    public List<Shift> getAllShifts() {
-        return shiftRepository.findAll();
-    }
-
-    @Override
-    public Shift getShiftById(Long id) {
-        return shiftRepository.findById(id)
-                .orElseThrow(() -> new ShiftNotFoundException(id));
-    }
-
-    @Override
-    public Shift createShift(CreateShiftDto dto, String username) {
-        Manager manager = getManagerByUsername(username);
-        Shift shift = new Shift(dto.date(), dto.start(), dto.end(), manager);
-        return shiftRepository.save(shift);
-    }
-
-    @Override
-    public Shift updateShift(Long id, CreateShiftDto dto, String username) {
-        Manager manager = getManagerByUsername(username);
-        Shift shift = getShiftById(id);
-
-        shift.setDate(dto.date());
-        shift.setStart(dto.start());
-        shift.setEnd(dto.end());
-        shift.setManager(manager);
-
-        return shiftRepository.save(shift);
-    }
-
-    @Override
-    public void deleteShift(Long id, String username) {
-        getManagerByUsername(username);
-        if (!shiftRepository.existsById(id)) {
-            throw new ShiftNotFoundException(id);
-        }
-        shiftRepository.deleteById(id);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/service/viewRefreshers/MvRefresher.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/viewRefreshers/MvRefresher.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package finki.db.tasty_tabs.service.viewRefreshers;
-
-import finki.db.tasty_tabs.repository.AnalyticsAdminRepository;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.support.TransactionSynchronization;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
-
-@Component
-@RequiredArgsConstructor
-public class MvRefresher {
-    private final AnalyticsAdminRepository analyticsAdminRepository;
-
-    public void refreshPaymentsMvAfterCommit() {
-        // If there is an active transaction, run after commit; otherwise run immediately.
-        if (TransactionSynchronizationManager.isSynchronizationActive()) {
-            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
-                @Override
-                public void afterCommit() {
-                    analyticsAdminRepository.refreshMvPaymentsDailyChannelConcurrently();
-                }
-            });
-        } else {
-            analyticsAdminRepository.refreshMvPaymentsDailyChannelConcurrently();
-        }
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/utils/JwtProvider.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/utils/JwtProvider.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,36 +1,0 @@
-package finki.db.tasty_tabs.utils;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.Keys;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-
-@Component
-public class JwtProvider {
-    @Value("${jwt.secret}")
-    private String jwtSecret;
-    @Value("${jwt.expiration}")
-    private long jwtExpiration;
-
-    public String generateToken(String email) {
-        return Jwts.builder()
-                .setSubject(String.valueOf(email)) // Use user ID as the subject
-                .setIssuedAt(new Date()) // Token issue time
-                .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration)) // Token expiration
-                .signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes()), SignatureAlgorithm.HS256) // HMAC-SHA256 signing
-                .compact();
-    }
-
-    public Claims validateToken(String token) {
-        return Jwts.parserBuilder()
-                .setSigningKey(jwtSecret.getBytes())
-                .build()
-                .parseClaimsJws(token)
-                .getBody();
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/AnalyticsController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/AnalyticsController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,79 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-import finki.db.tasty_tabs.service.AnalyticsExtraService;
-import finki.db.tasty_tabs.service.AnalyticsService;
-import finki.db.tasty_tabs.web.dto.AnalyticsByChannelResponse;
-import finki.db.tasty_tabs.web.dto.*;
-import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.web.bind.annotation.*;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-@RestController
-@RequestMapping("/api/analytics")
-@RequiredArgsConstructor
-public class AnalyticsController {
-
-    private final AnalyticsService analyticsService;
-    private final AnalyticsExtraService analyticsExtraService;
-
-    // Existing MV endpoint
-    @GetMapping("/reveunueByChannel")
-    public AnalyticsByChannelResponse paymentsDailyChannel(
-            @RequestParam(required = false)
-            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
-            @RequestParam(required = false)
-            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to
-    ) {
-        return analyticsService.getPaymentsDailyChannel(from, to);
-    }
-
-    // 1) Server performance & revenue ranking (last 3 months)
-    @GetMapping("/servers/performance")
-    public List<ServerPerformanceDto> serverPerformance() {
-        return analyticsExtraService.serverPerformanceLast3Months();
-    }
-
-    // 2) Monthly revenue vs labor cost
-    @GetMapping("/monthly-revenue-vs-labor")
-    public List<MonthlyRevenueVsLaborDto> monthlyRevenueVsLabor() {
-        return analyticsExtraService.monthlyRevenueVsLabor();
-    }
-
-    // 3) Daily operations summary (default 30 days)
-    @GetMapping("/daily-ops")
-    public List<DailyOpsDto> dailyOps(@RequestParam(defaultValue = "30") int days) {
-        return analyticsExtraService.dailyOpsSummary(days);
-    }
-
-    // 4) Top products (defaults: last 90 days, top 10)
-    @GetMapping("/top-products")
-    public List<TopProductDto> topProducts(
-            @RequestParam(defaultValue = "90") int days,
-            @RequestParam(defaultValue = "10") int limit) {
-        return analyticsExtraService.topProducts(days, limit);
-    }
-
-    // 5) Revenue by shift period (dynamic view -> generic rows)
-    @GetMapping("/revenue-by-shift-period")
-    public List<Map<String, Object>> revenueByShiftPeriod() {
-        return analyticsExtraService.revenueByShiftPeriodView();
-    }
-
-    // 6) Revenue split (calls your SQL function) by order date
-    @GetMapping("/revenue-split")
-    public List<RevenueSplitDto> revenueSplit(
-            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
-            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to
-    ) {
-        return analyticsExtraService.revenueSplit(from, to);
-    }
-
-    // 7) Managers' shifts above monthly average (current year)
-    @GetMapping("/managers/shifts-above-avg")
-    public List<ManagerShiftAboveAvgDto> shiftsAboveAvg() {
-        return analyticsExtraService.managersShiftsAboveMonthlyAvgCurrentYear();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/AssignmentController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/AssignmentController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,110 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.service.AssignmentService;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.CreateAssignmentDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/assignments")
-@Tag(name = "Assignment API", description = "Endpoints for managing shift assignments (Manager only)")
-public class AssignmentController {
-
-    private final AssignmentService assignmentService;
-
-    public AssignmentController(AssignmentService assignmentService) {
-        this.assignmentService = assignmentService;
-    }
-
-    @Operation(summary = "Get all assignments")
-    @GetMapping
-    public List<AssignmentDto> getAllAssignments() {
-        return assignmentService.getAllAssignments()
-                .stream()
-                .map(AssignmentDto::fromAssignment)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get assignment by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<AssignmentDto> getAssignmentById(@PathVariable Long id) {
-        return ResponseEntity.ok(AssignmentDto.fromAssignment(assignmentService.getAssignmentById(id)));
-    }
-
-    @Operation(summary = "Create assignment (Manager only)")
-    @PostMapping
-    public ResponseEntity<AssignmentDto> createAssignment(@RequestBody CreateAssignmentDto dto, Authentication authentication) {
-        try {
-            String managerEmail = authentication.getName();
-            Assignment assignment = assignmentService.createAssignment(dto, managerEmail);
-            return ResponseEntity.status(HttpStatus.CREATED).body(AssignmentDto.fromAssignment(assignment));
-        } catch (SecurityException e) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
-        }
-    }
-
-    @Operation(summary = "Update assignment (Manager only)")
-    @PutMapping("/{id}")
-    public ResponseEntity<AssignmentDto> updateAssignment(@PathVariable Long id, @RequestBody CreateAssignmentDto dto, Authentication authentication) {
-        try {
-            String managerEmail = authentication.getName();
-            Assignment updated = assignmentService.updateAssignment(id, dto, managerEmail);
-            return ResponseEntity.ok(AssignmentDto.fromAssignment(updated));
-        } catch (SecurityException e) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
-        }
-    }
-
-    @Operation(summary = "Delete assignment (Manager only)")
-    @DeleteMapping("/{id}")
-    public ResponseEntity<Void> deleteAssignment(@PathVariable Long id, Authentication authentication) {
-        try {
-            String managerEmail = authentication.getName();
-            assignmentService.deleteAssignment(id, managerEmail);
-            return ResponseEntity.noContent().build();
-        } catch (SecurityException e) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
-        }
-    }
-
-    @Operation(summary = "Employee clocks in their shift")
-    @PostMapping("/{id}/clockin")
-    public ResponseEntity<AssignmentDto> clockInShift(
-            @PathVariable Long id,
-            @RequestParam(required = false) LocalDateTime clockInTime,
-            Authentication authentication) {
-        try {
-            String employeeEmail = authentication.getName();
-            LocalDateTime timeToSet = clockInTime != null ? clockInTime : LocalDateTime.now();
-            Assignment assignment = assignmentService.clockInShift(id, employeeEmail, timeToSet);
-            return ResponseEntity.ok(AssignmentDto.fromAssignment(assignment));
-        } catch (SecurityException e) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
-        }
-    }
-
-    @Operation(summary = "Employee clocks out their shift")
-    @PostMapping("/{id}/clockout")
-    public ResponseEntity<AssignmentDto> clockOutShift(
-            @PathVariable Long id,
-            @RequestParam(required = false) LocalDateTime clockOutTime,
-            Authentication authentication) {
-        try {
-            String employeeEmail = authentication.getName();
-            LocalDateTime timeToSet = clockOutTime != null ? clockOutTime : LocalDateTime.now();
-            Assignment assignment = assignmentService.clockOutShift(id, employeeEmail, timeToSet);
-            return ResponseEntity.ok(AssignmentDto.fromAssignment(assignment));
-        } catch (SecurityException e) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
-        }
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/AuthController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/AuthController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,32 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.service.AuthService;
-import finki.db.tasty_tabs.web.dto.AuthDto;
-import finki.db.tasty_tabs.web.dto.request.RegisterRequest;
-import finki.db.tasty_tabs.web.dto.request.AuthRequest;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("/api/auth")
-@Tag(name = "Auth", description = "Authentication and authorization endpoints")
-@RequiredArgsConstructor
-public class AuthController {
-    private final AuthService authService;
-
-    @PostMapping("/login")
-    public ResponseEntity<AuthDto> authenticate(@Valid @RequestBody AuthRequest authDto) {
-        return ResponseEntity.ok(authService.authenticate(authDto.username(), authDto.password()));
-    }
-
-    @PostMapping("/register")
-    public ResponseEntity<AuthDto> register(@Valid @RequestBody RegisterRequest registerRequest) {
-        return ResponseEntity.ok(authService.register(registerRequest));
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/CategoryController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/CategoryController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,63 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Category;
-import finki.db.tasty_tabs.service.CategoryService;
-import finki.db.tasty_tabs.web.dto.CategoryDto;
-import finki.db.tasty_tabs.web.dto.CreateCategoryDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/categories")
-@Tag(name = "Category API", description = "Endpoints for managing product categories")
-public class CategoryController {
-
-    private final CategoryService categoryService;
-
-    public CategoryController(CategoryService categoryService) {
-        this.categoryService = categoryService;
-    }
-
-    @Operation(summary = "Get all categories")
-    @GetMapping
-    public ResponseEntity<List<CategoryDto>> findAll() {
-        List<CategoryDto> categories = categoryService.getAllCategories().stream()
-                .map(CategoryDto::from)
-                .collect(Collectors.toList());
-        return ResponseEntity.ok(categories);
-    }
-
-    @Operation(summary = "Get category by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<CategoryDto> findById(@PathVariable Long id) {
-        Category category = categoryService.findById(id);
-        return ResponseEntity.ok(CategoryDto.from(category));
-    }
-
-    @Operation(summary = "Create category")
-    @PostMapping("/add")
-    public ResponseEntity<CategoryDto> save(@RequestBody CreateCategoryDto createCategoryDto) {
-        Category saved = categoryService.createCategory(createCategoryDto.toCategory());
-        return ResponseEntity.status(HttpStatus.CREATED).body(CategoryDto.from(saved));
-    }
-
-    @Operation(summary = "Update category")
-    @PutMapping("/edit/{id}")
-    public ResponseEntity<CategoryDto> update(@PathVariable Long id, @RequestBody CreateCategoryDto createCategoryDto) {
-        Category updated = categoryService.updateCategory(id, createCategoryDto.toCategory());
-        return ResponseEntity.ok(CategoryDto.from(updated));
-    }
-
-    @Operation(summary = "Delete category")
-    @DeleteMapping("/delete/{id}")
-    public ResponseEntity<Void> deleteById(@PathVariable Long id) {
-        categoryService.deleteCategory(id);
-        return ResponseEntity.noContent().build();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/EmployeeController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/EmployeeController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,45 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.service.EmployeeService;
-import finki.db.tasty_tabs.web.dto.AssignmentDto;
-import finki.db.tasty_tabs.web.dto.CreateEmployeeRequest;
-import finki.db.tasty_tabs.web.dto.EmployeeDto;
-import finki.db.tasty_tabs.web.dto.ShiftDto;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/employees") // New Controller
-class EmployeeController {
-
-    private final EmployeeService employeeService;
-
-    public EmployeeController(EmployeeService employeeService) {
-        this.employeeService = employeeService;
-    }
-
-    // This endpoint would be secured in a real application to ensure only managers can access it.
-    @PostMapping("/manager/create")
-    @PreAuthorize("hasRole('MANAGER')")
-    public ResponseEntity<Employee> createEmployee(@RequestBody CreateEmployeeRequest request) {
-        Employee newEmployee = employeeService.createEmployee(request);
-        return ResponseEntity.status(HttpStatus.CREATED).body(newEmployee);
-    }
-
-    @GetMapping()
-    public ResponseEntity<List<EmployeeDto>> getAllEmployees() {
-        List<EmployeeDto> employees = employeeService.getAllEmployees();
-        return ResponseEntity.ok(employees);
-    }
-
-    @GetMapping("/{employeeId}/shifts/next")
-    public ResponseEntity<AssignmentDto> getNextShift(@PathVariable Long employeeId) {
-        AssignmentDto nextShift = employeeService.getNextShiftForEmployee(employeeId);
-        return ResponseEntity.ok(nextShift);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/OrderController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/OrderController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,185 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-import finki.db.tasty_tabs.entity.Order;
-import finki.db.tasty_tabs.service.OrderService;
-import finki.db.tasty_tabs.web.dto.CreateOrderDto;
-import finki.db.tasty_tabs.web.dto.CreateOrderItemDto;
-import finki.db.tasty_tabs.web.dto.OrderDto;
-import finki.db.tasty_tabs.web.dto.OrderItemDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/orders")
-@Tag(name = "Order API", description = "Endpoints for managing orders")
-@RequiredArgsConstructor
-public class OrderController {
-
-    private final OrderService orderService;
-
-    @Operation(summary = "Get all orders (both online and tab)")
-    @GetMapping
-    public List<OrderDto> getAllOrders() {
-        return orderService.findAll().stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get any order by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<OrderDto> getOrderById(@PathVariable Long id) {
-        return ResponseEntity.ok(OrderDto.from(orderService.findById(id)));
-    }
-
-    @Operation(summary = "Update an existing order")
-    @PutMapping("/{id}")
-    public ResponseEntity<OrderDto> updateOrder(@PathVariable Long id, @RequestBody CreateOrderDto dto) {
-        return ResponseEntity.ok(OrderDto.from(orderService.updateOrder(id, dto)));
-    }
-
-    @Operation(summary = "Delete an order by ID")
-    @DeleteMapping("/{id}")
-    public ResponseEntity<Void> deleteOrder(@PathVariable Long id) {
-        orderService.deleteOrder(id);
-        return ResponseEntity.noContent().build();
-    }
-
-    @Operation(summary = "Calculate total price of an order")
-    @GetMapping("/{id}/total-price")
-    public ResponseEntity<Double> calculateTotalPrice(@PathVariable Long id) {
-        return ResponseEntity.ok(orderService.calculateTotalPrice(id));
-    }
-
-    @Operation(summary = "Update the status of an order")
-    @PatchMapping("/{id}/status")
-    public ResponseEntity<Void> updateOrderStatus(@PathVariable Long id, @RequestBody Map<String, String> status) {
-        orderService.updateOrderStatus(id, status.get("status"));
-        return ResponseEntity.noContent().build();
-    }
-
-    @Operation(summary = "Cancel an order")
-    @PatchMapping("/{orderId}/cancel")
-    public ResponseEntity<OrderDto> cancelOrder(@PathVariable Long orderId) {
-        return ResponseEntity.ok(OrderDto.from(orderService.cancelOrder(orderId)));
-    }
-
-    // Order Item Endpoints
-    @Operation(summary = "Add an item to an existing order")
-    @PostMapping("/{orderId}/items")
-    public ResponseEntity<OrderItemDto> addItemToOrder(@PathVariable Long orderId, @RequestBody CreateOrderItemDto itemDto) {
-        return ResponseEntity.ok(OrderItemDto.from(orderService.addItemToOrder(orderId, itemDto)));
-    }
-
-    @Operation(summary = "Decrease the quantity of a specific order item")
-    @DeleteMapping("/items/{orderItemId}")
-    public ResponseEntity<Void> decreaseOrderItemQuantity(@PathVariable Long orderItemId) {
-        orderService.decreaseOrderItemQuantity(orderItemId);
-        return ResponseEntity.noContent().build();
-    }
-
-    @Operation(summary = "Update an existing order item")
-    @PutMapping("/items/{orderItemId}")
-    public ResponseEntity<OrderItemDto> updateOrderItem(@PathVariable Long orderItemId, @RequestBody CreateOrderItemDto itemDto) {
-        return ResponseEntity.ok(OrderItemDto.from(orderService.updateOrderItem(orderItemId, itemDto)));
-    }
-
-    @Operation(summary = "Delete an order item by ID")
-    @DeleteMapping("/items/{orderItemId}/delete")
-    public ResponseEntity<Void> deleteOrderItem(@PathVariable Long orderItemId) {
-        orderService.deleteOrderItem(orderItemId);
-        return ResponseEntity.noContent().build();
-    }
-
-    @Operation(summary = "Mark an order item as processed")
-    @PatchMapping("/items/{orderItemId}/process")
-    public ResponseEntity<OrderItemDto> processOrderItem(@PathVariable Long orderItemId) {
-        return ResponseEntity.ok(OrderItemDto.from(orderService.processOrderItem(orderItemId)));
-    }
-
-    // Online Order Endpoints
-    @Operation(summary = "Create a new online order for a logged-in customer")
-    @PostMapping("/online")
-    public ResponseEntity<OrderDto> createOnlineOrder(@RequestBody CreateOrderDto dto, Authentication authentication) {
-        String userEmail = authentication.getName();
-        return ResponseEntity.ok(OrderDto.from(orderService.createOnlineOrder(dto, userEmail)));
-    }
-
-    @Operation(summary = "Get all online orders")
-    @GetMapping("/online")
-    public List<OrderDto> getAllOnlineOrders() {
-        return orderService.findAllOnlineOrders().stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get a specific online order by ID")
-    @GetMapping("/online/{id}")
-    public ResponseEntity<OrderDto> getOnlineOrderById(@PathVariable Long id) {
-        return ResponseEntity.ok(OrderDto.from(orderService.findOnlineOrderById(id)));
-    }
-
-    @Operation(summary = "Get all online orders for a specific customer")
-    @GetMapping("/online/customer/{customerId}")
-    public List<OrderDto> getOnlineOrdersByCustomer(@PathVariable Long customerId) {
-        return orderService.findOnlineOrdersByCustomer(customerId).stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    // Tab Order Endpoints
-    @Operation(summary = "Create a new tab order for a logged-in front staff member")
-    @PostMapping("/tab")
-    public ResponseEntity<OrderDto> createTabOrder(@RequestBody CreateOrderDto dto, Authentication authentication) {
-        String userEmail = authentication.getName();
-        return ResponseEntity.ok(OrderDto.from(orderService.createTabOrder(dto, userEmail)));
-    }
-
-    @Operation(summary = "Get all tab orders")
-    @GetMapping("/tab")
-    public List<OrderDto> getAllTabOrders() {
-        return orderService.findAllTabOrders().stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get a specific tab order by ID")
-    @GetMapping("/tab/{id}")
-    public ResponseEntity<OrderDto> getTabOrderById(@PathVariable Long id) {
-        return ResponseEntity.ok(OrderDto.from(orderService.findTabOrderById(id)));
-    }
-
-    @Operation(summary = "Get all tab orders for a specific table on a given date (defaults to today)")
-    @GetMapping("/tab/table/{tableNumber}")
-    public List<OrderDto> getTabOrdersByTableAndDate(
-            @PathVariable Integer tableNumber,
-            @RequestParam(required = false, defaultValue = "#{T(java.time.LocalDate).now()}") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
-        return orderService.findTabOrdersByTableAndDate(tableNumber, date).stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get all open orders (pending or in-progress)")
-    @GetMapping("/open")
-    public List<OrderDto> getOpenOrders() {
-        return orderService.findOpenOrders().stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get all closed orders (completed, canceled, or delivered)")
-    @GetMapping("/closed")
-    public List<OrderDto> getClosedOrders() {
-        return orderService.findClosedOrders().stream()
-                .map(OrderDto::from)
-                .collect(Collectors.toList());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/PaymentController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/PaymentController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,61 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-
-import finki.db.tasty_tabs.entity.Payment;
-import finki.db.tasty_tabs.service.PaymentService;
-import finki.db.tasty_tabs.web.dto.CreatePaymentDto;
-import finki.db.tasty_tabs.web.dto.PaymentDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/payments")
-@Tag(name = "Payment API", description = "Endpoints for managing payments")
-@RequiredArgsConstructor
-public class PaymentController {
-
-    private final PaymentService paymentService;
-
-    @Operation(summary = "Create a new payment for an order")
-    @PostMapping
-    public ResponseEntity<PaymentDto> createPayment(@RequestBody CreatePaymentDto dto) {
-        Payment newPayment = paymentService.createPayment(dto);
-        return ResponseEntity.ok(PaymentDto.from(newPayment));
-    }
-
-    @Operation(summary = "Get a payment by its ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<PaymentDto> getPaymentById(@PathVariable Long id) {
-        Payment payment = paymentService.findPaymentById(id);
-        return ResponseEntity.ok(PaymentDto.from(payment));
-    }
-
-    @Operation(summary = "Get a payment by its associated order ID")
-    @GetMapping("/order/{orderId}")
-    public ResponseEntity<PaymentDto> getPaymentByOrderId(@PathVariable Long orderId) {
-        Payment payment = paymentService.findPaymentByOrderId(orderId);
-        return ResponseEntity.ok(PaymentDto.from(payment));
-    }
-
-    @Operation(summary = "Get all payments")
-    @GetMapping
-    public List<PaymentDto> getAllPayments() {
-        return paymentService.findAllPayments().stream()
-                .map(PaymentDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Update an existing payment")
-    @PutMapping("/{id}")
-    public ResponseEntity<PaymentDto> updatePayment(@PathVariable Long id, @RequestBody CreatePaymentDto dto) {
-        Payment updatedPayment = paymentService.updatePayment(id, dto);
-        return ResponseEntity.ok(PaymentDto.from(updatedPayment));
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/ProductController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/ProductController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,70 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Product;
-import finki.db.tasty_tabs.service.ProductService;
-import finki.db.tasty_tabs.web.dto.CreateProductDto;
-import finki.db.tasty_tabs.web.dto.ProductDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/products")
-@Tag(name = "Product API", description = "Endpoints for managing products")
-public class ProductController {
-
-    private final ProductService productService;
-
-    public ProductController(ProductService productService) {
-        this.productService = productService;
-    }
-
-    @Operation(summary = "Get all products")
-    @GetMapping
-    public ResponseEntity<List<ProductDto>> findAll() {
-        List<ProductDto> products = productService.getAllProducts().stream()
-                .map(ProductDto::from)
-                .collect(Collectors.toList());
-        return ResponseEntity.ok(products);
-    }
-
-    @Operation(summary = "Get product by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<ProductDto> findById(@PathVariable Long id) {
-        return ResponseEntity.ok(ProductDto.from(productService.findById(id)));
-    }
-
-    @Operation(summary = "Search products by name")
-    @GetMapping("/search")
-    public ResponseEntity<List<ProductDto>> findByName(@RequestParam String name) {
-        List<ProductDto> products = productService.getProductsByName(name).stream()
-                .map(ProductDto::from)
-                .collect(Collectors.toList());
-        return ResponseEntity.ok(products);
-    }
-
-    @Operation(summary = "Create new product")
-    @PostMapping("/add")
-    public ResponseEntity<ProductDto> save(@RequestBody CreateProductDto dto) {
-        return ResponseEntity.status(HttpStatus.CREATED).body(ProductDto.from(productService.createProduct(dto)));
-    }
-
-    @Operation(summary = "Update product")
-    @PutMapping("/edit/{id}")
-    public ResponseEntity<ProductDto> update(@PathVariable Long id, @RequestBody CreateProductDto dto) {
-        var updatedProduct = productService.updateProduct(id, dto);
-        return ResponseEntity.ok(ProductDto.from(updatedProduct));
-    }
-
-    @Operation(summary = "Delete product")
-    @DeleteMapping("/delete/{id}")
-    public ResponseEntity<Void> delete(@PathVariable Long id) {
-        productService.deleteProduct(id);
-        return ResponseEntity.noContent().build();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/ReservationController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/ReservationController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,101 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Reservation;
-import finki.db.tasty_tabs.service.ReservationService;
-import finki.db.tasty_tabs.web.dto.CreateReservationDto;
-import finki.db.tasty_tabs.web.dto.ReservationDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/reservations")
-@Tag(name = "Reservation API", description = "Endpoints for managing reservations")
-@RequiredArgsConstructor
-public class ReservationController {
-
-    private final ReservationService reservationService;
-
-    @Operation(summary = "Get all reservations")
-    @GetMapping
-    public List<ReservationDto> getAll() {
-        return reservationService.getAllReservationsWithStatus();
-    }
-
-    @Operation(summary = "Get reservation by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<ReservationDto> getById(@PathVariable Long id) {
-        return ResponseEntity.ok(ReservationDto.from(reservationService.getReservationById(id)));
-    }
-
-    @Operation(summary = "Create new reservation")
-    @PostMapping("/add")
-    public ResponseEntity<ReservationDto> create(@RequestBody CreateReservationDto dto, Authentication authentication) {
-        String userEmail = authentication.getName();
-        Reservation reservation = reservationService.createReservation(dto, userEmail);
-        return ResponseEntity.ok(ReservationDto.from(reservation));
-    }
-
-    @Operation(summary = "Update reservation")
-    @PutMapping("/edit/{id}")
-    public ResponseEntity<ReservationDto> update(@PathVariable Long id, @RequestBody CreateReservationDto dto, Authentication authentication) {
-        String userEmail = authentication.getName();
-        Reservation reservation = reservationService.updateReservation(id, dto, userEmail);
-        return ResponseEntity.ok(ReservationDto.from(reservation));
-    }
-
-    @Operation(summary = "Delete reservation")
-    @DeleteMapping("/delete/{id}")
-    public ResponseEntity<Void> delete(@PathVariable Long id) {
-        reservationService.deleteReservation(id);
-        return ResponseEntity.noContent().build();
-    }
-
-    @Operation(summary = "Get all reservations made by the logged-in user")
-    @GetMapping("/myReservations")
-    public List<ReservationDto> getMyReservations(Authentication authentication) {
-        String username = authentication.getName();
-        return reservationService.getAllReservationsByUser(username)
-                .stream()
-                .map(ReservationDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Accept a reservation by a front staff member")
-    @PostMapping("/accept/{reservationId}/table/{tableNumber}")
-    public ResponseEntity<ReservationDto> acceptReservation(
-            @PathVariable Long reservationId,
-            @PathVariable Long tableNumber,
-            Authentication authentication
-    ) {
-        String frontStaffEmail = authentication.getName();
-        reservationService.acceptReservation(reservationId,frontStaffEmail,tableNumber);
-        return ResponseEntity.ok(ReservationDto.from(reservationService.getReservationById(reservationId)));
-    }
-    @Operation(summary = "Get all reservations for today")
-    @GetMapping("/today")
-    public List<ReservationDto> getTodayReservations() {
-        return reservationService.getAllReservationsForToday()
-                .stream()
-                .map(ReservationDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get all reservations for a specific date")
-    @GetMapping("/by-date")
-    public List<ReservationDto> getReservationsByDate(
-            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
-        return reservationService.getAllReservationsForDate(date)
-                .stream()
-                .map(ReservationDto::from)
-                .collect(Collectors.toList());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/RestaurantTableController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/RestaurantTableController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,65 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-import finki.db.tasty_tabs.service.RestaurantTableService;
-import finki.db.tasty_tabs.web.dto.CreateRestaurantTableDto;
-import finki.db.tasty_tabs.web.dto.RestaurantTableDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.http.HttpStatus;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/tables")
-@Tag(name = "Restaurant Table API", description = "Endpoints for managing restaurant tables")
-public class RestaurantTableController {
-
-    private final RestaurantTableService restaurantTableService;
-
-    public RestaurantTableController(RestaurantTableService restaurantTableService) {
-        this.restaurantTableService = restaurantTableService;
-    }
-
-    @Operation(summary = "Get all tables", description = "Retrieves a list of all restaurant tables.")
-    @GetMapping
-    public List<RestaurantTableDto> findAll() {
-        return restaurantTableService.getAll()
-                .stream()
-                .map(RestaurantTableDto::from)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get a table by table number", description = "Finds a table by its table number.")
-    @GetMapping("/{tableNumber}")
-    public ResponseEntity<RestaurantTableDto> findById(@PathVariable Long tableNumber) {
-        return ResponseEntity.ok(RestaurantTableDto.from(restaurantTableService.findById(tableNumber)));
-                }
-
-    @Operation(summary = "Add a new table", description = "Creates a new restaurant table.")
-    @PostMapping("/add")
-    public ResponseEntity<RestaurantTableDto> save(@RequestBody CreateRestaurantTableDto dto) {
-        RestaurantTable newTable = restaurantTableService.createTable(dto.toRestaurantTable());
-        return ResponseEntity.status(HttpStatus.CREATED).body(RestaurantTableDto.from(newTable));
-    }
-
-    @Operation(summary = "Update an existing table", description = "Updates a restaurant table by its table number.")
-    @PutMapping("/edit/{tableNumber}")
-    public ResponseEntity<RestaurantTableDto> update(
-            @PathVariable Long tableNumber,
-            @RequestBody CreateRestaurantTableDto dto
-    ) {
-        RestaurantTable updatedTable = restaurantTableService.updateTable(tableNumber, dto.toRestaurantTable());
-        return ResponseEntity.ok(RestaurantTableDto.from(updatedTable));
-    }
-
-    @Operation(summary = "Delete a table", description = "Deletes a restaurant table by its table number.")
-    @DeleteMapping("/delete/{tableNumber}")
-    public ResponseEntity<Void> deleteById(@PathVariable Long tableNumber) {
-        restaurantTableService.deleteTable(tableNumber);
-        return ResponseEntity.noContent().build();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/controllers/ShiftController.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/controllers/ShiftController.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,67 +1,0 @@
-package finki.db.tasty_tabs.web.controllers;
-
-import finki.db.tasty_tabs.entity.Shift;
-import finki.db.tasty_tabs.service.ShiftService;
-import finki.db.tasty_tabs.web.dto.CreateShiftDto;
-import finki.db.tasty_tabs.web.dto.ShiftDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/shifts")
-@Tag(name = "Shift API", description = "Endpoints for managing work shifts (Manager only)")
-public class ShiftController {
-
-    private final ShiftService shiftService;
-
-    public ShiftController(ShiftService shiftService) {
-        this.shiftService = shiftService;
-    }
-
-    @Operation(summary = "Get all shifts")
-    @GetMapping
-    public List<ShiftDto> getAllShifts() {
-        return shiftService.getAllShifts()
-                .stream()
-                .map(ShiftDto::fromShift)
-                .collect(Collectors.toList());
-    }
-
-    @Operation(summary = "Get shift by ID")
-    @GetMapping("/{id}")
-    public ResponseEntity<ShiftDto> getShiftById(@PathVariable Long id) {
-        Shift shift = shiftService.getShiftById(id);
-        return ResponseEntity.ok(ShiftDto.fromShift(shift));
-    }
-
-    @Operation(summary = "Create a shift (Manager only)")
-    @PostMapping
-    public ResponseEntity<ShiftDto> createShift(@RequestBody CreateShiftDto dto, Authentication authentication) {
-        String username = authentication.getName();
-        Shift shift = shiftService.createShift(dto, username);
-        return new ResponseEntity<>(ShiftDto.fromShift(shift), HttpStatus.CREATED);
-    }
-
-    @Operation(summary = "Update a shift (Manager only)")
-    @PutMapping("/{id}")
-    public ResponseEntity<ShiftDto> updateShift(@PathVariable Long id, @RequestBody CreateShiftDto dto, Authentication authentication) {
-        String username = authentication.getName();
-        Shift updatedShift = shiftService.updateShift(id, dto, username);
-        return ResponseEntity.ok(ShiftDto.fromShift(updatedShift));
-    }
-
-    @Operation(summary = "Delete a shift (Manager only)")
-    @DeleteMapping("/{id}")
-    public ResponseEntity<Void> deleteShift(@PathVariable Long id, Authentication authentication) {
-        String username = authentication.getName();
-        shiftService.deleteShift(id, username);
-        return ResponseEntity.noContent().build();
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/AnalyticsByChannelResponse.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/AnalyticsByChannelResponse.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.util.List;
-
-public record AnalyticsByChannelResponse(
-        LocalDate from,
-        LocalDate to,
-        List<ChannelTableDto> channels,
-        Long grandTotalPaidOrders,
-        BigDecimal grandTotalRevenue,
-        BigDecimal grandTotalTips
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/AssignmentDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/AssignmentDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.entity.Manager;
-
-import java.time.LocalDateTime;
-
-public record AssignmentDto(
-        Long id,
-        LocalDateTime clockInTime,
-        LocalDateTime clockOutTime,
-        ManagerDto manager,
-        EmployeeDto employee,
-        ShiftDto shift
-) {
-    public static AssignmentDto fromAssignment(Assignment assignment) {
-        return new AssignmentDto(
-                assignment.getId(),
-                assignment.getClockInTime(),
-                assignment.getClockOutTime(),
-                ManagerDto.from(assignment.getManager()),
-                EmployeeDto.from(assignment.getEmployee()),
-                ShiftDto.fromShiftBasic(assignment.getShift())
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/AuthDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/AuthDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-public record AuthDto (
-        String token,
-        UserDto user
-){
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CategoryDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CategoryDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Category;
-
-public record CategoryDto(
-        Long id,
-        String name,
-        Boolean isAvailable
-) {
-    public static CategoryDto from(Category category) {
-        return new CategoryDto(category.getId(), category.getName(), category.getIsAvailable());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ChannelTableDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ChannelTableDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-public record ChannelTableDto(
-        String channel,
-        List<PaymentsDailyChannelDto> data,
-        Long totalPaidOrders,
-        BigDecimal totalRevenue,
-        BigDecimal totalTips
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ClockInRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ClockInRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-
-@Data
-public class ClockInRequest {
-    private Long employeeId;
-    private Long shiftId;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateAssignmentDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateAssignmentDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Assignment;
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.entity.Manager;
-import finki.db.tasty_tabs.entity.Shift;
-
-import java.time.LocalDateTime;
-
-public record CreateAssignmentDto(
-        LocalDateTime clockInTime,
-        LocalDateTime clockOutTime,
-        Long employeeId,
-        Long shiftId
-) {
-    public Assignment toAssignment(Employee employee,Shift shift) {
-        return new Assignment(
-                clockInTime,
-                clockOutTime,
-                employee,
-                shift
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateCategoryDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateCategoryDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Category;
-
-public record CreateCategoryDto(
-        String name,
-        Boolean isAvailable
-) {
-    public Category toCategory() {
-        return new Category(name, isAvailable);
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateEmployeeRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateEmployeeRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.EmployeeType;
-
-public record CreateEmployeeRequest(
-        String email,
-        String password,
-        String street,
-        String city,
-        String phoneNumber,
-        Double netSalary,
-        Double grossSalary,
-        EmployeeType employeeType,
-        Long staffRoleId, // Only for FrontStaff/BackStaff
-        Double tipPercent // Only for FrontStaff
-) {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOnlineOrderRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOnlineOrderRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-import java.time.LocalDateTime;
-import java.util.List;
-
-
-@Data
-public class CreateOnlineOrderRequest {
-    private Long customerId;
-    private String deliveryAddress;
-    private List<OrderItemRequest> items;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOrderDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOrderDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.util.List;
-
-public record CreateOrderDto(
-        List<CreateOrderItemDto> orderItems,
-        String status,
-        String type, // "online" or "tab"
-        String deliveryAddress, // For OnlineOrder
-        Long tableNumber // For TabOrder
-) { }
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOrderItemDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateOrderItemDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-public record CreateOrderItemDto(
-        Long productId,
-        Integer quantity,
-        Double price,
-        Boolean isProcessed
-) { }
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreatePaymentDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreatePaymentDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-public record CreatePaymentDto(
-        Double tipAmount,
-        String paymentType,
-        Double amount,
-        Long orderId
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateProductDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateProductDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-public record CreateProductDto(
-        String name,
-        Double price,
-        String taxClass,
-        String description,
-        Boolean manageInventory,
-        Long categoryId,
-        Integer quantity,
-        Integer restockLevel
-) {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateReservationDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateReservationDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-import java.time.LocalDateTime;
-
-public record CreateReservationDto(
-        Integer stayLength,
-        LocalDateTime datetime,
-        Integer numberOfPeople
-) {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateRestaurantTableDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateRestaurantTableDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-
-public record CreateRestaurantTableDto(
-        Long tableNumber,
-        Integer seatCapacity
-) {
-    public RestaurantTable toRestaurantTable(){
-        return new RestaurantTable(tableNumber,seatCapacity);
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateShiftDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateShiftDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import finki.db.tasty_tabs.entity.Manager;
-import finki.db.tasty_tabs.entity.Shift;
-import lombok.Data;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-public record CreateShiftDto(
-        LocalDate date,
-        LocalDateTime start,
-        LocalDateTime end
-) {
-    public Shift toShift(Manager manager) {
-        return new Shift(
-                date,
-                start,
-                end
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/CreateTabOrderRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/CreateTabOrderRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-import java.time.LocalDateTime;
-import java.util.List;
-@Data
-public class CreateTabOrderRequest {
-    private Integer tableNumber;
-    private Long frontStaffId;
-    private List<OrderItemRequest> items;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/DailyOpsDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/DailyOpsDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public record DailyOpsDto(
-        LocalDate operationDate,
-        Long totalReservations,
-        Long totalOrders,
-        Long uniqueCustomers,
-        Long activeEmployees,
-        BigDecimal dailyRevenue
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/EmployeeDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/EmployeeDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Employee;
-import finki.db.tasty_tabs.entity.UserType;
-
-import java.time.LocalDateTime;
-
-public record EmployeeDto(
-        Long id,
-        String email,
-        String street,
-        String city,
-        String phoneNumber,
-        Double netSalary,
-        Double grossSalary,
-        UserType userType
-) {
-    public static EmployeeDto from(Employee employee) {
-        return new EmployeeDto(
-                employee.getId(),
-                employee.getEmail(),
-                employee.getStreet(),
-                employee.getCity(),
-                employee.getPhoneNumber(),
-                employee.getNetSalary(),
-                employee.getGrossSalary(),
-                employee.getUserType()
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/FrontStaffDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/FrontStaffDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,29 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.FrontStaff;
-
-public record FrontStaffDto(
-        Long id,
-        String email,
-        String street,
-        String city,
-        String phoneNumber,
-        Double netSalary,
-        Double grossSalary,
-        Double tipPercent,
-        String staffRoleName
-) {
-    public static FrontStaffDto from(FrontStaff user) {
-        return new FrontStaffDto(
-                user.getId(),
-                user.getEmail(),
-                user.getStreet(),
-                user.getCity(),
-                user.getPhoneNumber(),
-                user.getNetSalary(),
-                user.getGrossSalary(),
-                user.getTipPercent(),     // Предпоставуваме дека User има tipPercent
-                user.getStaffRole().getName()   // Предпоставуваме дека User има staffRoleName
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ManagerDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ManagerDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import finki.db.tasty_tabs.entity.Manager;
-import lombok.Data;
-import java.time.LocalDateTime;
-import java.util.List;
-public record ManagerDto(
-        Long id,
-        String email
-        ){
-    public static ManagerDto from(Manager manager){
-        return new ManagerDto(manager.getId(), manager.getEmail());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ManagerShiftAboveAvgDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ManagerShiftAboveAvgDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.LocalTime;
-
-public record ManagerShiftAboveAvgDto(
-        String period,               // YYYY-MM
-        Long shiftId,
-        LocalDate shiftDate,
-        LocalTime shiftStartTime,
-        LocalTime shiftEndTime,
-        String managerEmail,
-        BigDecimal shiftRevenue,
-        BigDecimal avgRevenuePerShift,
-        BigDecimal aboveBy
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/MonthlyRevenueVsLaborDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/MonthlyRevenueVsLaborDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-
-public record MonthlyRevenueVsLaborDto(
-        String period,                // YYYY-MM
-        BigDecimal totalRevenue,
-        BigDecimal totalLaborCost,
-        BigDecimal laborAsPercentOfRevenue
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/OrderDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/OrderDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,68 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.OnlineOrder;
-import finki.db.tasty_tabs.entity.Order;
-import finki.db.tasty_tabs.entity.TabOrder;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public record OrderDto(
-        Long id,
-        LocalDateTime timestamp,
-        String status,
-        String type,
-        String customerName,
-        String deliveryAddress,
-        Long tableNumber,
-        String frontStaffName,
-        List<OrderItemDto> orderItems
-) {
-    public static OrderDto from(Order order) {
-        if (order instanceof OnlineOrder onlineOrder) {
-            return new OrderDto(
-                    onlineOrder.getId(),
-                    onlineOrder.getTimestamp(),
-                    onlineOrder.getStatus(),
-                    "ONLINE",
-                    onlineOrder.getCustomer().getEmail(),
-                    onlineOrder.getDeliveryAddress(),
-                    null,
-                    null,
-                    onlineOrder.getOrderItems().stream()
-                            .map(OrderItemDto::from)
-                            .collect(Collectors.toList())
-            );
-        } else if (order instanceof TabOrder tabOrder) {
-            return new OrderDto(
-                    tabOrder.getId(),
-                    tabOrder.getTimestamp(),
-                    tabOrder.getStatus(),
-                    "TAB",
-                    null,
-                    null,
-                    tabOrder.getRestaurantTable().getTableNumber(),
-                    tabOrder.getEmployee().getEmail(),
-                    tabOrder.getOrderItems().stream()
-                            .map(OrderItemDto::from)
-                            .collect(Collectors.toList())
-            );
-        } else {
-            // Handle the base Order entity if needed
-            return new OrderDto(
-                    order.getId(),
-                    order.getTimestamp(),
-                    order.getStatus(),
-                    "base",
-                    null,
-                    null,
-                    null,
-                    null,
-                    order.getOrderItems().stream()
-                            .map(OrderItemDto::from)
-                            .collect(Collectors.toList())
-            );
-        }
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/OrderItemDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/OrderItemDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-
-import finki.db.tasty_tabs.entity.OrderItem;
-import java.time.LocalDateTime;
-
-public record OrderItemDto(
-        Long id,
-        Integer quantity,
-        Double price,
-        Boolean isProcessed,
-        LocalDateTime timestamp,
-        Long productId,
-        String productName
-) {
-    public static OrderItemDto from(OrderItem orderItem) {
-        return new OrderItemDto(
-                orderItem.getId(),
-                orderItem.getQuantity(),
-                orderItem.getPrice(),
-                orderItem.getIsProcessed(),
-                orderItem.getTimestamp(),
-                orderItem.getProduct().getId(),
-                orderItem.getProduct().getName()
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/OrderItemRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/OrderItemRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-import java.time.LocalDateTime;
-import java.util.List;
-@Data
-public class OrderItemRequest {
-    private Long productId;
-    private int quantity;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/PaymentDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/PaymentDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Payment;
-
-import java.time.LocalDateTime;
-
-public record PaymentDto(
-        Long id,
-        Double tipAmount,
-        LocalDateTime timestamp,
-        String paymentType,
-        Double amount,
-        Long orderId
-) {
-    public static PaymentDto from(Payment payment) {
-        return new PaymentDto(
-                payment.getId(),
-                payment.getTipAmount(),
-                payment.getTimestamp(),
-                payment.getPaymentType(),
-                payment.getAmount(),
-                payment.getOrder().getId()
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/PaymentsDailyChannelDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/PaymentsDailyChannelDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public record PaymentsDailyChannelDto(
-        LocalDate day,
-        String channel,
-        Long paidOrdersCnt,
-        BigDecimal revenue,
-        BigDecimal tipTotal
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ProductDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ProductDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.Product;
-
-public record ProductDto(
-        Long id,
-        String name,
-        Double price,
-        String taxClass,
-        String description,
-        Boolean manageInventory,
-        CategoryDto category
-) {
-    public static ProductDto from(Product product) {
-        return new ProductDto(product.getId(),
-                product.getName(),
-                product.getPrice(),
-                product.getTaxClass(),
-                product.getDescription(),
-                product.getManageInventory(),
-                CategoryDto.from(product.getCategory())
-                );
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ReservationDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ReservationDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,44 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import finki.db.tasty_tabs.entity.Reservation;
-import java.time.LocalDateTime;
-public record ReservationDto(
-        Long id,
-        Integer stayLength,
-        LocalDateTime datetime,
-        LocalDateTime creationTimestamp,
-        Integer numberOfPeople,
-        String email,
-        String status, // "ACCEPTED" | "PENDING"
-        Long assignedTableNumber,     // null if not accepted
-        String frontStaffName         // null if not accepted; using email as fallback
-) {
-    // legacy factory (defaults to PENDING)
-    public static ReservationDto from(Reservation r) {
-        return new ReservationDto(
-                r.getId(),
-                r.getStayLength(),
-                r.getDatetime(),
-                r.getCreationTimestamp(),
-                r.getNumberOfPeople(),
-                r.getUser().getEmail(),
-                "PENDING",
-                null,
-                null
-        );
-    }
-
-    // new factory with accepted flag
-    public static ReservationDto from(Reservation r, boolean accepted, Long tableNumber, String frontStaffName) {
-        return new ReservationDto(
-                r.getId(),
-                r.getStayLength(),
-                r.getDatetime(),
-                r.getCreationTimestamp(),
-                r.getNumberOfPeople(),
-                r.getUser().getEmail(),
-                accepted ? "ACCEPTED" : "PENDING",
-                accepted ? tableNumber : null,
-                accepted ? frontStaffName : null
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/RestaurantTableDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/RestaurantTableDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.RestaurantTable;
-
-public record RestaurantTableDto(
-        Long tableNumber,
-        Integer seatCapacity
-) {
-    public static RestaurantTableDto from(RestaurantTable table){
-        return new RestaurantTableDto(table.getTableNumber(), table.getSeatCapacity());
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/RevenueSplitDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/RevenueSplitDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-
-import java.math.BigDecimal;
-
-public record RevenueSplitDto(
-        String orderType,            // Online Orders | Tab Orders
-        BigDecimal totalRevenue
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ServerPerformanceDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ServerPerformanceDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-
-public record ServerPerformanceDto(
-        String serverEmail,
-        Long totalAssignments,
-        Long ordersProcessed,
-        BigDecimal totalRevenueGenerated,
-        Integer revenueRank,
-        Integer ordersRank,
-        BigDecimal avgOrdersPerShift,
-        BigDecimal avgOrderValue
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/ShiftDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/ShiftDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,40 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import finki.db.tasty_tabs.entity.Manager;
-import finki.db.tasty_tabs.entity.Shift;
-import lombok.Data;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-public record ShiftDto(
-        Long id,
-        LocalDate date,
-        LocalDateTime start,
-        LocalDateTime end,
-        ManagerDto manager,
-        List<AssignmentDto> assignments
-) {
-    public static ShiftDto fromShift(Shift shift) {
-        return new ShiftDto(
-                shift.getId(),
-                shift.getDate(),
-                shift.getStart(),
-                shift.getEnd(),
-                ManagerDto.from(shift.getManager()),
-                shift.getAssignments().stream()
-                        .map(AssignmentDto::fromAssignment)
-                        .toList()
-        );
-    }
-    public static ShiftDto fromShiftBasic(Shift shift) {
-        return new ShiftDto(
-                shift.getId(),
-                shift.getDate(),
-                shift.getStart(),
-                shift.getEnd(),
-                ManagerDto.from(shift.getManager()),
-                null
-        );
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/TopProductDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/TopProductDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import java.math.BigDecimal;
-
-public record TopProductDto(
-        Long productId,
-        String productName,
-        String categoryName,
-        Long totalQuantitySold,
-        BigDecimal totalRevenue,
-        BigDecimal revenueSharePercent
-) {}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/TransferTabRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/TransferTabRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-import lombok.Data;
-import java.time.LocalDateTime;
-import java.util.List;
-@Data
-public class TransferTabRequest {
-    private Long newFrontStaffId;
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/UserDto.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/UserDto.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package finki.db.tasty_tabs.web.dto;
-
-import finki.db.tasty_tabs.entity.User;
-import finki.db.tasty_tabs.entity.UserType;
-
-public record UserDto(
-        Long id,
-        String email,
-        String street,
-        String city,
-        String phoneNumber,
-        UserType userType
-) {
-    public static UserDto from(User user) {
-        return new UserDto(
-                user.getId(),
-                user.getEmail(),
-                user.getStreet(),
-                user.getCity(),
-                user.getPhoneNumber(),
-                user.getUserType()
-        );
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/request/AuthRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/request/AuthRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package finki.db.tasty_tabs.web.dto.request;
-
-public record AuthRequest(
-        String username,
-        String password
-) {
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/dto/request/RegisterRequest.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/dto/request/RegisterRequest.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package finki.db.tasty_tabs.web.dto.request;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-@Data
-public class RegisterRequest {
-    @NotNull(message = "Email is required")
-    private String email;
-    @NotNull(message = "Password is required")
-    private String password;
-    private String passwordConfirmation;
-    private String firstName;
-    private String lastName;
-
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/exception/FilterExceptionHandler.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/exception/FilterExceptionHandler.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,75 +1,0 @@
-package finki.db.tasty_tabs.web.exception;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.jsonwebtoken.ExpiredJwtException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatusCode;
-import org.springframework.http.ProblemDetail;
-import org.springframework.security.authentication.AccountStatusException;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authorization.AuthorizationDeniedException;
-
-import java.io.IOException;
-import java.net.URI;
-import java.nio.file.AccessDeniedException;
-import java.security.SignatureException;
-
-@Slf4j
-public class FilterExceptionHandler {
-
-    // Handle an exception within a filter using the same ErrorResponse structure.
-    public static void handleException(HttpServletRequest request,
-                                       HttpServletResponse response,
-                                       Exception exception) throws IOException {
-        // Convert exception -> ErrorResponse just like your GlobalExceptionHandler.
-        ProblemDetail errorDetail = createErrorResponse(exception);
-        errorDetail.setInstance(URI.create(request.getRequestURI()));
-
-        // Write the ErrorResponse as JSON to response
-        response.setStatus(errorDetail.getStatus());
-        response.setContentType("application/json");
-
-        // For JSON serialization, you can use Jackson's ObjectMapper if available.
-        String json = new ObjectMapper().writeValueAsString(errorDetail);
-        response.getWriter().write(json);
-        response.getWriter().flush();
-    }
-
-    private static ProblemDetail createErrorResponse(Exception exception) {
-        ProblemDetail detail = null;
-
-        if (exception instanceof BadCredentialsException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(401), exception.getMessage());
-            detail.setProperty("description", "The username or password is incorrect");
-        } else if (exception instanceof AccountStatusException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            detail.setProperty("description", "The account is locked");
-        } else if (exception instanceof AccessDeniedException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            detail.setProperty("description", "You are not authorized to access this resource");
-        } else if (exception instanceof SignatureException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            detail.setProperty("description", "The JWT signature is invalid");
-        } else if (exception instanceof ExpiredJwtException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(401), exception.getMessage());
-            detail.setProperty("description", "The JWT token has expired");
-        } else if (exception instanceof AuthorizationDeniedException) {
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            detail.setProperty("description", "You are not authorized to access this resource");
-        }
-
-        if (detail == null) {
-            // Unknown/unhandled exception
-            detail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(500), exception.getMessage());
-            detail.setProperty("description", "Unknown internal server error.");
-        }
-
-//        log.warn("An exception occurred: {}", exception.getMessage(), exception);
-
-        return detail;
-    }
-}
-
-
Index: ckend/src/main/java/finki/db/tasty_tabs/web/exception/GlobalExceptionHandler.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/exception/GlobalExceptionHandler.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,102 +1,0 @@
-package finki.db.tasty_tabs.web.exception;
-
-import finki.db.tasty_tabs.entity.exceptions.DomainException;
-import io.jsonwebtoken.ExpiredJwtException;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.security.SignatureException;
-import io.swagger.v3.oas.annotations.Hidden;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatusCode;
-import org.springframework.http.ProblemDetail;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.authentication.AccountStatusException;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authorization.AuthorizationDeniedException;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-@RestControllerAdvice
-@Hidden
-@Slf4j
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler({JwtException.class, AuthenticationException.class, SignatureException.class, AccessDeniedException.class})
-    public ProblemDetail handleSecurityExceptions(Exception exception) {
-        ProblemDetail errorDetail = null;
-
-        log.warn("Security exception: {}", exception.getMessage());
-        if (exception instanceof BadCredentialsException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(401), exception.getMessage());
-            errorDetail.setProperty("description", "The username or password is incorrect");
-
-        }
-        if (exception instanceof IllegalStateException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(400), exception.getMessage());
-            errorDetail.setProperty("description", "Invalid operation: " + exception.getMessage());
-        }
-
-        if (exception instanceof AccountStatusException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "The account is locked");
-        }
-
-        if (exception instanceof AuthorizationDeniedException){
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "You are not authorized to access this resource");
-        }
-
-        if (exception instanceof AccessDeniedException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "You are not authorized to access this resource");
-        }
-        if (exception instanceof SecurityException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "You are not authorized to perform this action");
-        }
-
-        if (exception instanceof SignatureException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "The JWT signature is invalid");
-        }
-
-        if (exception instanceof ExpiredJwtException) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(403), exception.getMessage());
-            errorDetail.setProperty("description", "The JWT token has expired");
-        }
-
-        if (errorDetail == null) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(500), exception.getMessage());
-            errorDetail.setProperty("description", "Unknown internal server error.");
-        }
-
-        return errorDetail;
-    }
-
-    @ExceptionHandler(DomainException.class)
-    public ProblemDetail handleDomainExceptions(DomainException exception) {
-        ProblemDetail errorDetail = null;
-
-        log.warn("Domain exception: {}", exception.getMessage());
-
-        if (errorDetail == null) {
-            errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(500), exception.getMessage());
-            errorDetail.setProperty("description", "Unknown internal server error.");
-        }
-
-        return errorDetail;
-    }
-
-
-    @ExceptionHandler(Exception.class)
-    public ProblemDetail handleAllExceptions(Exception exception) {
-        ProblemDetail errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(500), exception.getMessage());
-        errorDetail.setProperty("description", "Unknown internal server error.");
-
-        log.error("Unexpected exception: {}", exception.getMessage(), exception);
-
-        exception.printStackTrace();
-
-        return errorDetail;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/filter/HttpLoggingFilter.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/filter/HttpLoggingFilter.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,59 +1,0 @@
-package finki.db.tasty_tabs.web.filter;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.slf4j.MDC;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-@Slf4j
-public class HttpLoggingFilter extends OncePerRequestFilter {
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest req,
-                                    HttpServletResponse resp,
-                                    FilterChain chain)
-            throws ServletException, IOException {
-
-        long start = System.currentTimeMillis();
-        try {
-            chain.doFilter(req, resp);
-        } finally {
-            MDC.put("userId", resolveUserId());
-
-            // — compute duration —
-            long timeMs = System.currentTimeMillis() - start;
-            MDC.put("timeMs", String.valueOf(timeMs));
-
-            // — log it —
-//            log.info("Request: {} {} {} from {} – {}ms",
-//                    resp.getStatus(),
-//                    req.getMethod(),
-//                    req.getRequestURI(),
-//                    req.getRemoteAddr(),
-//                    timeMs);
-
-            // — cleanup —
-            MDC.clear();
-        }
-    }
-
-    private String resolveUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
-            return "ANONYMOUS";
-        }
-        return ((UserDetails) authentication.getPrincipal()).getUsername();
-    }
-}
-
Index: ckend/src/main/java/finki/db/tasty_tabs/web/filter/JwtAuthenticationFilter.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/filter/JwtAuthenticationFilter.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,89 +1,0 @@
-package finki.db.tasty_tabs.web.filter;
-
-import finki.db.tasty_tabs.utils.JwtProvider;
-import finki.db.tasty_tabs.web.exception.FilterExceptionHandler;
-import finki.db.tasty_tabs.web.security.CustomUserDetailsService;
-import finki.db.tasty_tabs.web.security.PublicUrlProvider;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.ExpiredJwtException;
-import io.jsonwebtoken.JwtException;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.authorization.AuthorizationDeniedException;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-@Slf4j
-public class JwtAuthenticationFilter extends OncePerRequestFilter {
-    private final JwtProvider jwtProvider;
-    private final CustomUserDetailsService userDetailsService;
-    private final PublicUrlProvider publicUrlProvider;
-    private final AntPathMatcher pathMatcher = new AntPathMatcher();
-
-    // Update the constructor
-    public JwtAuthenticationFilter(JwtProvider jwtProvider, CustomUserDetailsService userDetailsService, PublicUrlProvider publicUrlProvider) {
-        this.jwtProvider = jwtProvider;
-        this.userDetailsService = userDetailsService;
-        this.publicUrlProvider = publicUrlProvider;
-    }
-
-    // --- NEW METHOD ---
-    @Override
-    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
-        // This method tells Spring to SKIP this filter entirely if the path matches.
-        return publicUrlProvider.getPublicPaths().stream()
-                .anyMatch(p -> (pathMatcher.match(p, request.getServletPath()) && "GET".equalsIgnoreCase(request.getMethod())) || ("/api/auth/login".equals(request.getServletPath()) && "POST".equalsIgnoreCase(request.getMethod())) || ("/api/auth/register".equals(request.getServletPath()) && "POST".equalsIgnoreCase(request.getMethod())));
-    }
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request,
-                                    HttpServletResponse response,
-                                    FilterChain filterChain) throws ServletException, IOException {
-        try {
-            String token = resolveToken(request);
-            Claims claims = jwtProvider.validateToken(token);
-            if (claims != null) {
-                String email = claims.getSubject();
-                UserDetails userDetails = userDetailsService.loadUserByUserId(email);
-
-                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
-                        userDetails, null, userDetails.getAuthorities());
-                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-
-                SecurityContextHolder.getContext().setAuthentication(authentication);
-                log.debug("JWT token validated");
-            }
-            filterChain.doFilter(request, response);
-        } catch (ExpiredJwtException e) {
-            log.debug("JWT token expired: {}", e.getMessage());
-            FilterExceptionHandler.handleException(request, response, e);
-        } catch (AuthorizationDeniedException e) {
-//            log.debug("Authorization denied: {}", e.getMessage());
-            FilterExceptionHandler.handleException(request, response, e);
-        } catch (JwtException e) {
-//            log.debug("JWT token invalid: {}", e.getMessage());
-            filterChain.doFilter(request, response);
-        } catch (Exception e) {
-            FilterExceptionHandler.handleException(request, response, e);
-        }
-    }
-
-    private String resolveToken(HttpServletRequest request) {
-        String bearerToken = request.getHeader("Authorization");
-        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
-            return bearerToken.substring(7);
-        }
-        return null;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/AuthenticatedUser.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/AuthenticatedUser.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import org.springframework.security.core.userdetails.UserDetails;
-
-/**
- * An extension of Spring Security's UserDetails to include the user's primary ID.
- */
-public interface AuthenticatedUser extends UserDetails {
-    Long getId();
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/CustomUserDetails.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/CustomUserDetails.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,63 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import finki.db.tasty_tabs.entity.User;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-
-import java.util.Collection;
-import java.util.List;
-
-// Implement the interface we defined earlier
-public class CustomUserDetails implements AuthenticatedUser {
-
-    private final User user;
-
-    public CustomUserDetails(User user) {
-        this.user = user;
-    }
-
-    // --- This is the custom method our Aspect needs ---
-    @Override
-    public Long getId() {
-        return user.getId();
-    }
-    
-    // --- Below are the standard UserDetails methods ---
-    @Override
-    public Collection<? extends GrantedAuthority> getAuthorities() {
-        // You should map your employee type/role to a Spring Security authority
-        // The "ROLE_" prefix is a standard convention.
-        return List.of(new SimpleGrantedAuthority("ROLE_" + user.getUserType().name()));
-    }
-
-    @Override
-    public String getPassword() {
-        return user.getPassword();
-    }
-
-    @Override
-    public String getUsername() {
-        // The "username" in this context is the email
-        return user.getEmail();
-    }
-
-    @Override
-    public boolean isAccountNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isAccountNonLocked() {
-        return true;
-    }
-
-    @Override
-    public boolean isCredentialsNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/CustomUserDetailsService.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/CustomUserDetailsService.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-public interface CustomUserDetailsService extends UserDetailsService {
-    UserDetails loadUserByUserId(String email);
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/PublicUrlProvider.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/PublicUrlProvider.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,18 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-@Component
-public class PublicUrlProvider {
-    // This list should exactly match the permitAll() paths in your SecurityConfig
-    private static final List<String> PUBLIC_PATHS = List.of(
-            "/swagger-ui/**",
-            "/v3/api-docs/**"
-    );
-
-    public List<String> getPublicPaths() {
-        return PUBLIC_PATHS;
-    }
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/SecurityConfig.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/SecurityConfig.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,75 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import finki.db.tasty_tabs.web.filter.JwtAuthenticationFilter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
-import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
-import java.util.Arrays;
-import java.util.List;
-
-@Configuration
-@EnableWebSecurity
-@EnableMethodSecurity
-public class SecurityConfig {
-    @Autowired
-    private JwtAuthenticationFilter jwtAuthenticationFilter;
-
-    @Bean
-    public SecurityFilterChain securityFilterChain(HttpSecurity http, PublicUrlProvider publicUrlProvider) throws Exception {
-        http
-                .csrf(AbstractHttpConfigurer::disable)
-                .cors(cors -> cors.configurationSource(corsConfigurationSource())) // Enable CORS
-                .authorizeHttpRequests(authorize -> authorize
-                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
-                        .requestMatchers(HttpMethod.GET, publicUrlProvider.getPublicPaths().toArray(new String[0])).permitAll()
-                        .requestMatchers("/api/auth/login").permitAll()
-                        .requestMatchers("/api/auth/register").permitAll()
-                        .anyRequest().authenticated()
-                )
-                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
-                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
-
-        return http.build();
-    }
-
-    @Bean
-    public CorsConfigurationSource corsConfigurationSource() {
-        CorsConfiguration config = new CorsConfiguration();
-        config.setAllowedOrigins(List.of("*")); // Or specific origins
-        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
-        config.setAllowedHeaders(List.of("*"));
-        config.setAllowCredentials(false);
-        config.setMaxAge(3600L);
-
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", config);
-        return source;
-    }
-
-    @Bean
-    public PasswordEncoder passwordEncoder() {
-        return new BCryptPasswordEncoder();
-    }
-
-    @Bean
-    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
-        return authenticationConfiguration.getAuthenticationManager();
-    }
-
-}
Index: ckend/src/main/java/finki/db/tasty_tabs/web/security/UserDetailsServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/web/security/UserDetailsServiceImpl.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,72 +1,0 @@
-package finki.db.tasty_tabs.web.security;
-
-import finki.db.tasty_tabs.entity.*;
-import finki.db.tasty_tabs.repository.UserRepository;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-import java.util.HashSet;
-import java.util.Set;
-
-@Slf4j
-@Service
-public class UserDetailsServiceImpl implements CustomUserDetailsService {
-    @Autowired
-    private UserRepository userRepository;
-
-    @Override
-    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-//        log.debug("Loading user by username: {}", username);
-        User user = userRepository.findByEmail(username)
-                .orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + username));
-
-        return getUserDetails(user);
-    }
-
-    @Override
-    public UserDetails loadUserByUserId(String email) {
-        log.debug("Loading user by ID: {}", email);
-        User user = userRepository.findByEmail(email)
-                .orElseThrow(() -> new UsernameNotFoundException("User not found with ID: " + email));
-
-        return getUserDetails(user);
-    }
-
-    private UserDetails getUserDetails(User user){
-
-
-        // Convert roles to Spring Security's authorities
-        Set<GrantedAuthority> authorities = new HashSet<>();
-        GrantedAuthority grantedAuthority = getGrantedAuthority(user);
-
-        authorities.add(grantedAuthority);
-        log.debug("Applying role {} to user {}", grantedAuthority.getAuthority(), user.getId());
-
-        return new CustomUserDetails(user);
-    }
-
-    private static GrantedAuthority getGrantedAuthority(User user) {
-        GrantedAuthority grantedAuthority;
-
-        if(user instanceof Employee){
-            if(user instanceof Manager){
-                grantedAuthority = new SimpleGrantedAuthority("ROLE_MANAGER");
-            } else if(user instanceof FrontStaff){
-                grantedAuthority = new SimpleGrantedAuthority("ROLE_FRONT_STAFF");
-            } else if (user instanceof BackStaff){
-                grantedAuthority = new SimpleGrantedAuthority("ROLE_BACKSTAFF");
-            } else {
-                grantedAuthority = new SimpleGrantedAuthority("ROLE_EMPLOYEE");
-            }
-        } else{
-            grantedAuthority = new SimpleGrantedAuthority("ROLE_CUSTOMER");
-        }
-        return grantedAuthority;
-    }
-}
-
Index: ckend/src/main/resources/application-test.properties
===================================================================
--- backend/src/main/resources/application-test.properties	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-spring.datasource.url=jdbc:postgresql://localhost:5435/spring_boot_db
-spring.datasource.username=springuser
-spring.datasource.password=springpassword
-spring.datasource.driver-class-name=org.postgresql.Driver
-spring.jpa.hibernate.ddl-auto=none
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
-spring.flyway.enabled=false
Index: ckend/src/main/resources/application.properties
===================================================================
--- backend/src/main/resources/application.properties	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-spring.application.name=Tasty Tabs
-spring.datasource.url=jdbc:postgresql://localhost:5434/db_202425z_va_prj_tasty_tabs
-spring.datasource.username=db_202425z_va_prj_tasty_tabs_owner
-spring.datasource.password=99e003badb51
-#spring.profiles.active=test
-springdoc.api-docs.enabled=true
-springdoc.swagger-ui.enabled=true
-jwt.secret=e249a8adbb3572a23f1520e69573aab8bc4b2eaf0bfab9c7a8d118a0c5d799aa
-jwt.expiration=86400000
-
-logging.level.finki=DEBUG
-logging.level.org.springframework=DEBUG
-
-spring.flyway.enabled=false
-spring.flyway.baseline-on-migrate=false
Index: ckend/src/main/resources/logback-spring.xml
===================================================================
--- backend/src/main/resources/logback-spring.xml	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,24 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
-
-    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
-
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <pattern>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p)
-                %clr([${spring.application.name:-},%X{traceId:-},%X{spanId:-}]){yellow} %clr([%t]){faint}
-                %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
-            </pattern>
-            <charset>UTF-8</charset>
-        </encoder>
-    </appender>
-
-    <root level="INFO">
-        <appender-ref ref="STDOUT"/>
-    </root>
-
-    <logger name="finki.db.tasty_tabs" level="DEBUG"/>
-    <logger name="org.springframework" level="WARN"/>
-    <logger name="org.hibernate.SQL" level="WARN"/>
-    <logger name="org.hibernate.type.descriptor.sql" level="WARN"/>
-</configuration>
Index: ckend/src/test/java/finki/db/tasty_tabs/TastyTabsApplicationTests.java
===================================================================
--- backend/src/test/java/finki/db/tasty_tabs/TastyTabsApplicationTests.java	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package finki.db.tasty_tabs;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TastyTabsApplicationTests {
-
-    @Test
-    void contextLoads() {
-    }
-
-}
Index: ontend/.gitignore
===================================================================
--- frontend/.gitignore	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,24 +1,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
Index: ontend/README.md
===================================================================
--- frontend/README.md	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,69 +1,0 @@
-# React + TypeScript + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-
-Currently, two official plugins are available:
-
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
-
-## Expanding the ESLint configuration
-
-If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
-
-```js
-export default tseslint.config([
-  globalIgnores(['dist']),
-  {
-    files: ['**/*.{ts,tsx}'],
-    extends: [
-      // Other configs...
-
-      // Remove tseslint.configs.recommended and replace with this
-      ...tseslint.configs.recommendedTypeChecked,
-      // Alternatively, use this for stricter rules
-      ...tseslint.configs.strictTypeChecked,
-      // Optionally, add this for stylistic rules
-      ...tseslint.configs.stylisticTypeChecked,
-
-      // Other configs...
-    ],
-    languageOptions: {
-      parserOptions: {
-        project: ['./tsconfig.node.json', './tsconfig.app.json'],
-        tsconfigRootDir: import.meta.dirname,
-      },
-      // other options...
-    },
-  },
-])
-```
-
-You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
-
-```js
-// eslint.config.js
-import reactX from 'eslint-plugin-react-x'
-import reactDom from 'eslint-plugin-react-dom'
-
-export default tseslint.config([
-  globalIgnores(['dist']),
-  {
-    files: ['**/*.{ts,tsx}'],
-    extends: [
-      // Other configs...
-      // Enable lint rules for React
-      reactX.configs['recommended-typescript'],
-      // Enable lint rules for React DOM
-      reactDom.configs.recommended,
-    ],
-    languageOptions: {
-      parserOptions: {
-        project: ['./tsconfig.node.json', './tsconfig.app.json'],
-        tsconfigRootDir: import.meta.dirname,
-      },
-      // other options...
-    },
-  },
-])
-```
Index: ontend/eslint.config.js
===================================================================
--- frontend/eslint.config.js	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,23 +1,0 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import reactHooks from 'eslint-plugin-react-hooks'
-import reactRefresh from 'eslint-plugin-react-refresh'
-import tseslint from 'typescript-eslint'
-import { globalIgnores } from 'eslint/config'
-
-export default tseslint.config([
-  globalIgnores(['dist']),
-  {
-    files: ['**/*.{ts,tsx}'],
-    extends: [
-      js.configs.recommended,
-      tseslint.configs.recommended,
-      reactHooks.configs['recommended-latest'],
-      reactRefresh.configs.vite,
-    ],
-    languageOptions: {
-      ecmaVersion: 2020,
-      globals: globals.browser,
-    },
-  },
-])
Index: ontend/index.html
===================================================================
--- frontend/index.html	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,13 +1,0 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite + React + TS</title>
-  </head>
-  <body>
-    <div id="root"></div>
-    <script type="module" src="/src/main.tsx"></script>
-  </body>
-</html>
Index: ontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,4735 +1,0 @@
-{
-  "name": "tasty-tabs-admin",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "tasty-tabs-admin",
-      "version": "0.0.0",
-      "dependencies": {
-        "@hookform/resolvers": "^5.2.1",
-        "@tailwindcss/vite": "^4.1.12",
-        "axios": "^1.11.0",
-        "react": "^19.1.1",
-        "react-dom": "^19.1.1",
-        "react-hook-form": "^7.62.0",
-        "react-router-dom": "^7.8.2",
-        "recharts": "^3.1.2",
-        "tailwindcss": "^4.1.12",
-        "zod": "^4.1.1"
-      },
-      "devDependencies": {
-        "@eslint/js": "^9.33.0",
-        "@types/react": "^19.1.10",
-        "@types/react-dom": "^19.1.7",
-        "@vitejs/plugin-react": "^5.0.0",
-        "eslint": "^9.33.0",
-        "eslint-plugin-react-hooks": "^5.2.0",
-        "eslint-plugin-react-refresh": "^0.4.20",
-        "globals": "^16.3.0",
-        "typescript": "~5.8.3",
-        "typescript-eslint": "^8.39.1",
-        "vite": "^7.1.2"
-      }
-    },
-    "node_modules/@ampproject/remapping": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
-      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@babel/code-frame": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
-      "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-validator-identifier": "^7.27.1",
-        "js-tokens": "^4.0.0",
-        "picocolors": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/compat-data": {
-      "version": "7.28.0",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
-      "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/core": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz",
-      "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@ampproject/remapping": "^2.2.0",
-        "@babel/code-frame": "^7.27.1",
-        "@babel/generator": "^7.28.3",
-        "@babel/helper-compilation-targets": "^7.27.2",
-        "@babel/helper-module-transforms": "^7.28.3",
-        "@babel/helpers": "^7.28.3",
-        "@babel/parser": "^7.28.3",
-        "@babel/template": "^7.27.2",
-        "@babel/traverse": "^7.28.3",
-        "@babel/types": "^7.28.2",
-        "convert-source-map": "^2.0.0",
-        "debug": "^4.1.0",
-        "gensync": "^1.0.0-beta.2",
-        "json5": "^2.2.3",
-        "semver": "^6.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/babel"
-      }
-    },
-    "node_modules/@babel/generator": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
-      "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.28.3",
-        "@babel/types": "^7.28.2",
-        "@jridgewell/gen-mapping": "^0.3.12",
-        "@jridgewell/trace-mapping": "^0.3.28",
-        "jsesc": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.27.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
-      "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/compat-data": "^7.27.2",
-        "@babel/helper-validator-option": "^7.27.1",
-        "browserslist": "^4.24.0",
-        "lru-cache": "^5.1.1",
-        "semver": "^6.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-globals": {
-      "version": "7.28.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
-      "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-module-imports": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
-      "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/traverse": "^7.27.1",
-        "@babel/types": "^7.27.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-module-transforms": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
-      "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-module-imports": "^7.27.1",
-        "@babel/helper-validator-identifier": "^7.27.1",
-        "@babel/traverse": "^7.28.3"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0"
-      }
-    },
-    "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
-      "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-string-parser": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
-      "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
-      "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-validator-option": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
-      "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helpers": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz",
-      "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/template": "^7.27.2",
-        "@babel/types": "^7.28.2"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/parser": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz",
-      "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.28.2"
-      },
-      "bin": {
-        "parser": "bin/babel-parser.js"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@babel/plugin-transform-react-jsx-self": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
-      "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.27.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-transform-react-jsx-source": {
-      "version": "7.27.1",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
-      "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.27.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/template": {
-      "version": "7.27.2",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
-      "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.27.1",
-        "@babel/parser": "^7.27.2",
-        "@babel/types": "^7.27.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/traverse": {
-      "version": "7.28.3",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz",
-      "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.27.1",
-        "@babel/generator": "^7.28.3",
-        "@babel/helper-globals": "^7.28.0",
-        "@babel/parser": "^7.28.3",
-        "@babel/template": "^7.27.2",
-        "@babel/types": "^7.28.2",
-        "debug": "^4.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/types": {
-      "version": "7.28.2",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
-      "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-string-parser": "^7.27.1",
-        "@babel/helper-validator-identifier": "^7.27.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
-      "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "aix"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
-      "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
-      "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
-      "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
-      "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
-      "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
-      "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
-      "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
-      "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
-      "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
-      "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
-      "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
-      "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
-      "cpu": [
-        "mips64el"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
-      "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
-      "cpu": [
-        "ppc64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
-      "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
-      "cpu": [
-        "riscv64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
-      "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
-      "cpu": [
-        "s390x"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
-      "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/netbsd-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
-      "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
-      "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/openbsd-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
-      "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
-      "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/openharmony-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
-      "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openharmony"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
-      "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
-      "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
-      "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
-      "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@eslint-community/eslint-utils": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
-      "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "eslint-visitor-keys": "^3.4.3"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
-      }
-    },
-    "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/@eslint-community/regexpp": {
-      "version": "4.12.1",
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
-      "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@eslint/config-array": {
-      "version": "0.21.0",
-      "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
-      "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@eslint/object-schema": "^2.1.6",
-        "debug": "^4.3.1",
-        "minimatch": "^3.1.2"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/config-helpers": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
-      "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/core": {
-      "version": "0.15.2",
-      "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
-      "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@types/json-schema": "^7.0.15"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/eslintrc": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
-      "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^10.0.1",
-        "globals": "^14.0.0",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^4.1.0",
-        "minimatch": "^3.1.2",
-        "strip-json-comments": "^3.1.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
-      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@eslint/js": {
-      "version": "9.34.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz",
-      "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://eslint.org/donate"
-      }
-    },
-    "node_modules/@eslint/object-schema": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
-      "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/plugin-kit": {
-      "version": "0.3.5",
-      "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
-      "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@eslint/core": "^0.15.2",
-        "levn": "^0.4.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@hookform/resolvers": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.1.tgz",
-      "integrity": "sha512-u0+6X58gkjMcxur1wRWokA7XsiiBJ6aK17aPZxhkoYiK5J+HcTx0Vhu9ovXe6H+dVpO6cjrn2FkJTryXEMlryQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@standard-schema/utils": "^0.3.0"
-      },
-      "peerDependencies": {
-        "react-hook-form": "^7.55.0"
-      }
-    },
-    "node_modules/@humanfs/core": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
-      "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18.0"
-      }
-    },
-    "node_modules/@humanfs/node": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
-      "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@humanfs/core": "^0.19.1",
-        "@humanwhocodes/retry": "^0.3.0"
-      },
-      "engines": {
-        "node": ">=18.18.0"
-      }
-    },
-    "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
-      "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/module-importer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=12.22"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/retry": {
-      "version": "0.4.3",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
-      "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@isaacs/fs-minipass": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
-      "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.0.4"
-      },
-      "engines": {
-        "node": ">=18.0.0"
-      }
-    },
-    "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.13",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
-      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.5.0",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      }
-    },
-    "node_modules/@jridgewell/remapping": {
-      "version": "2.3.5",
-      "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
-      "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      }
-    },
-    "node_modules/@jridgewell/resolve-uri": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
-      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.5.5",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
-      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
-      "license": "MIT"
-    },
-    "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.30",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
-      "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/resolve-uri": "^3.1.0",
-        "@jridgewell/sourcemap-codec": "^1.4.14"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@reduxjs/toolkit": {
-      "version": "2.8.2",
-      "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz",
-      "integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==",
-      "license": "MIT",
-      "dependencies": {
-        "@standard-schema/spec": "^1.0.0",
-        "@standard-schema/utils": "^0.3.0",
-        "immer": "^10.0.3",
-        "redux": "^5.0.1",
-        "redux-thunk": "^3.1.0",
-        "reselect": "^5.1.0"
-      },
-      "peerDependencies": {
-        "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
-        "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
-      },
-      "peerDependenciesMeta": {
-        "react": {
-          "optional": true
-        },
-        "react-redux": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@rolldown/pluginutils": {
-      "version": "1.0.0-beta.32",
-      "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz",
-      "integrity": "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.48.1.tgz",
-      "integrity": "sha512-rGmb8qoG/zdmKoYELCBwu7vt+9HxZ7Koos3pD0+sH5fR3u3Wb/jGcpnqxcnWsPEKDUyzeLSqksN8LJtgXjqBYw==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.48.1.tgz",
-      "integrity": "sha512-4e9WtTxrk3gu1DFE+imNJr4WsL13nWbD/Y6wQcyku5qadlKHY3OQ3LJ/INrrjngv2BJIHnIzbqMk1GTAC2P8yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.48.1.tgz",
-      "integrity": "sha512-+XjmyChHfc4TSs6WUQGmVf7Hkg8ferMAE2aNYYWjiLzAS/T62uOsdfnqv+GHRjq7rKRnYh4mwWb4Hz7h/alp8A==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.48.1.tgz",
-      "integrity": "sha512-upGEY7Ftw8M6BAJyGwnwMw91rSqXTcOKZnnveKrVWsMTF8/k5mleKSuh7D4v4IV1pLxKAk3Tbs0Lo9qYmii5mQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-freebsd-arm64": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.48.1.tgz",
-      "integrity": "sha512-P9ViWakdoynYFUOZhqq97vBrhuvRLAbN/p2tAVJvhLb8SvN7rbBnJQcBu8e/rQts42pXGLVhfsAP0k9KXWa3nQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ]
-    },
-    "node_modules/@rollup/rollup-freebsd-x64": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.48.1.tgz",
-      "integrity": "sha512-VLKIwIpnBya5/saccM8JshpbxfyJt0Dsli0PjXozHwbSVaHTvWXJH1bbCwPXxnMzU4zVEfgD1HpW3VQHomi2AQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.48.1.tgz",
-      "integrity": "sha512-3zEuZsXfKaw8n/yF7t8N6NNdhyFw3s8xJTqjbTDXlipwrEHo4GtIKcMJr5Ed29leLpB9AugtAQpAHW0jvtKKaQ==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.48.1.tgz",
-      "integrity": "sha512-leo9tOIlKrcBmmEypzunV/2w946JeLbTdDlwEZ7OnnsUyelZ72NMnT4B2vsikSgwQifjnJUbdXzuW4ToN1wV+Q==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.48.1.tgz",
-      "integrity": "sha512-Vy/WS4z4jEyvnJm+CnPfExIv5sSKqZrUr98h03hpAMbE2aI0aD2wvK6GiSe8Gx2wGp3eD81cYDpLLBqNb2ydwQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.48.1.tgz",
-      "integrity": "sha512-x5Kzn7XTwIssU9UYqWDB9VpLpfHYuXw5c6bJr4Mzv9kIv242vmJHbI5PJJEnmBYitUIfoMCODDhR7KoZLot2VQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.48.1.tgz",
-      "integrity": "sha512-yzCaBbwkkWt/EcgJOKDUdUpMHjhiZT/eDktOPWvSRpqrVE04p0Nd6EGV4/g7MARXXeOqstflqsKuXVM3H9wOIQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-ppc64-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.48.1.tgz",
-      "integrity": "sha512-UK0WzWUjMAJccHIeOpPhPcKBqax7QFg47hwZTp6kiMhQHeOYJeaMwzeRZe1q5IiTKsaLnHu9s6toSYVUlZ2QtQ==",
-      "cpu": [
-        "ppc64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.48.1.tgz",
-      "integrity": "sha512-3NADEIlt+aCdCbWVZ7D3tBjBX1lHpXxcvrLt/kdXTiBrOds8APTdtk2yRL2GgmnSVeX4YS1JIf0imFujg78vpw==",
-      "cpu": [
-        "riscv64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-riscv64-musl": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.48.1.tgz",
-      "integrity": "sha512-euuwm/QTXAMOcyiFCcrx0/S2jGvFlKJ2Iro8rsmYL53dlblp3LkUQVFzEidHhvIPPvcIsxDhl2wkBE+I6YVGzA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.48.1.tgz",
-      "integrity": "sha512-w8mULUjmPdWLJgmTYJx/W6Qhln1a+yqvgwmGXcQl2vFBkWsKGUBRbtLRuKJUln8Uaimf07zgJNxOhHOvjSQmBQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.48.1.tgz",
-      "integrity": "sha512-90taWXCWxTbClWuMZD0DKYohY1EovA+W5iytpE89oUPmT5O1HFdf8cuuVIylE6vCbrGdIGv85lVRzTcpTRZ+kA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.48.1.tgz",
-      "integrity": "sha512-2Gu29SkFh1FfTRuN1GR1afMuND2GKzlORQUP3mNMJbqdndOg7gNsa81JnORctazHRokiDzQ5+MLE5XYmZW5VWg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.48.1.tgz",
-      "integrity": "sha512-6kQFR1WuAO50bxkIlAVeIYsz3RUx+xymwhTo9j94dJ+kmHe9ly7muH23sdfWduD0BA8pD9/yhonUvAjxGh34jQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.48.1.tgz",
-      "integrity": "sha512-RUyZZ/mga88lMI3RlXFs4WQ7n3VyU07sPXmMG7/C1NOi8qisUg57Y7LRarqoGoAiopmGmChUhSwfpvQ3H5iGSQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.48.1.tgz",
-      "integrity": "sha512-8a/caCUN4vkTChxkaIJcMtwIVcBhi4X2PQRoT+yCK3qRYaZ7cURrmJFL5Ux9H9RaMIXj9RuihckdmkBX3zZsgg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@standard-schema/spec": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
-      "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
-      "license": "MIT"
-    },
-    "node_modules/@standard-schema/utils": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
-      "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
-      "license": "MIT"
-    },
-    "node_modules/@tailwindcss/node": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz",
-      "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/remapping": "^2.3.4",
-        "enhanced-resolve": "^5.18.3",
-        "jiti": "^2.5.1",
-        "lightningcss": "1.30.1",
-        "magic-string": "^0.30.17",
-        "source-map-js": "^1.2.1",
-        "tailwindcss": "4.1.12"
-      }
-    },
-    "node_modules/@tailwindcss/oxide": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz",
-      "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "dependencies": {
-        "detect-libc": "^2.0.4",
-        "tar": "^7.4.3"
-      },
-      "engines": {
-        "node": ">= 10"
-      },
-      "optionalDependencies": {
-        "@tailwindcss/oxide-android-arm64": "4.1.12",
-        "@tailwindcss/oxide-darwin-arm64": "4.1.12",
-        "@tailwindcss/oxide-darwin-x64": "4.1.12",
-        "@tailwindcss/oxide-freebsd-x64": "4.1.12",
-        "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12",
-        "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12",
-        "@tailwindcss/oxide-linux-arm64-musl": "4.1.12",
-        "@tailwindcss/oxide-linux-x64-gnu": "4.1.12",
-        "@tailwindcss/oxide-linux-x64-musl": "4.1.12",
-        "@tailwindcss/oxide-wasm32-wasi": "4.1.12",
-        "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12",
-        "@tailwindcss/oxide-win32-x64-msvc": "4.1.12"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-android-arm64": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz",
-      "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-darwin-arm64": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz",
-      "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-darwin-x64": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz",
-      "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-freebsd-x64": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz",
-      "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz",
-      "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz",
-      "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz",
-      "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz",
-      "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-x64-musl": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz",
-      "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-wasm32-wasi": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz",
-      "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==",
-      "bundleDependencies": [
-        "@napi-rs/wasm-runtime",
-        "@emnapi/core",
-        "@emnapi/runtime",
-        "@tybys/wasm-util",
-        "@emnapi/wasi-threads",
-        "tslib"
-      ],
-      "cpu": [
-        "wasm32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@emnapi/core": "^1.4.5",
-        "@emnapi/runtime": "^1.4.5",
-        "@emnapi/wasi-threads": "^1.0.4",
-        "@napi-rs/wasm-runtime": "^0.2.12",
-        "@tybys/wasm-util": "^0.10.0",
-        "tslib": "^2.8.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz",
-      "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz",
-      "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/vite": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.12.tgz",
-      "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@tailwindcss/node": "4.1.12",
-        "@tailwindcss/oxide": "4.1.12",
-        "tailwindcss": "4.1.12"
-      },
-      "peerDependencies": {
-        "vite": "^5.2.0 || ^6 || ^7"
-      }
-    },
-    "node_modules/@types/babel__core": {
-      "version": "7.20.5",
-      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
-      "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.20.7",
-        "@babel/types": "^7.20.7",
-        "@types/babel__generator": "*",
-        "@types/babel__template": "*",
-        "@types/babel__traverse": "*"
-      }
-    },
-    "node_modules/@types/babel__generator": {
-      "version": "7.27.0",
-      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
-      "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.0.0"
-      }
-    },
-    "node_modules/@types/babel__template": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
-      "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.1.0",
-        "@babel/types": "^7.0.0"
-      }
-    },
-    "node_modules/@types/babel__traverse": {
-      "version": "7.28.0",
-      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
-      "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.28.2"
-      }
-    },
-    "node_modules/@types/d3-array": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
-      "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
-      "license": "MIT"
-    },
-    "node_modules/@types/d3-color": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
-      "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
-      "license": "MIT"
-    },
-    "node_modules/@types/d3-ease": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
-      "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/d3-interpolate": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
-      "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/d3-color": "*"
-      }
-    },
-    "node_modules/@types/d3-path": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
-      "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
-      "license": "MIT"
-    },
-    "node_modules/@types/d3-scale": {
-      "version": "4.0.9",
-      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
-      "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/d3-time": "*"
-      }
-    },
-    "node_modules/@types/d3-shape": {
-      "version": "3.1.7",
-      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
-      "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/d3-path": "*"
-      }
-    },
-    "node_modules/@types/d3-time": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
-      "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
-      "license": "MIT"
-    },
-    "node_modules/@types/d3-timer": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
-      "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
-      "license": "MIT"
-    },
-    "node_modules/@types/estree": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
-      "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
-      "license": "MIT"
-    },
-    "node_modules/@types/json-schema": {
-      "version": "7.0.15",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
-      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@types/react": {
-      "version": "19.1.11",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz",
-      "integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==",
-      "devOptional": true,
-      "license": "MIT",
-      "dependencies": {
-        "csstype": "^3.0.2"
-      }
-    },
-    "node_modules/@types/react-dom": {
-      "version": "19.1.7",
-      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz",
-      "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "^19.0.0"
-      }
-    },
-    "node_modules/@types/use-sync-external-store": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
-      "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
-      "license": "MIT"
-    },
-    "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.40.0.tgz",
-      "integrity": "sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "8.40.0",
-        "@typescript-eslint/type-utils": "8.40.0",
-        "@typescript-eslint/utils": "8.40.0",
-        "@typescript-eslint/visitor-keys": "8.40.0",
-        "graphemer": "^1.4.0",
-        "ignore": "^7.0.0",
-        "natural-compare": "^1.4.0",
-        "ts-api-utils": "^2.1.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "@typescript-eslint/parser": "^8.40.0",
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
-      "version": "7.0.5",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
-      "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/@typescript-eslint/parser": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.40.0.tgz",
-      "integrity": "sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/scope-manager": "8.40.0",
-        "@typescript-eslint/types": "8.40.0",
-        "@typescript-eslint/typescript-estree": "8.40.0",
-        "@typescript-eslint/visitor-keys": "8.40.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/project-service": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.40.0.tgz",
-      "integrity": "sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/tsconfig-utils": "^8.40.0",
-        "@typescript-eslint/types": "^8.40.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.40.0.tgz",
-      "integrity": "sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.40.0",
-        "@typescript-eslint/visitor-keys": "8.40.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/tsconfig-utils": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.40.0.tgz",
-      "integrity": "sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.40.0.tgz",
-      "integrity": "sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.40.0",
-        "@typescript-eslint/typescript-estree": "8.40.0",
-        "@typescript-eslint/utils": "8.40.0",
-        "debug": "^4.3.4",
-        "ts-api-utils": "^2.1.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/types": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.40.0.tgz",
-      "integrity": "sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.40.0.tgz",
-      "integrity": "sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/project-service": "8.40.0",
-        "@typescript-eslint/tsconfig-utils": "8.40.0",
-        "@typescript-eslint/types": "8.40.0",
-        "@typescript-eslint/visitor-keys": "8.40.0",
-        "debug": "^4.3.4",
-        "fast-glob": "^3.3.2",
-        "is-glob": "^4.0.3",
-        "minimatch": "^9.0.4",
-        "semver": "^7.6.0",
-        "ts-api-utils": "^2.1.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
-      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
-      "version": "9.0.5",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
-      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
-      "version": "7.7.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
-      "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@typescript-eslint/utils": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.40.0.tgz",
-      "integrity": "sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.7.0",
-        "@typescript-eslint/scope-manager": "8.40.0",
-        "@typescript-eslint/types": "8.40.0",
-        "@typescript-eslint/typescript-estree": "8.40.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.40.0.tgz",
-      "integrity": "sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.40.0",
-        "eslint-visitor-keys": "^4.2.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@vitejs/plugin-react": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.1.tgz",
-      "integrity": "sha512-DE4UNaBXwtVoDJ0ccBdLVjFTWL70NRuWNCxEieTI3lrq9ORB9aOCQEKstwDXBl87NvFdbqh/p7eINGyj0BthJA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/core": "^7.28.3",
-        "@babel/plugin-transform-react-jsx-self": "^7.27.1",
-        "@babel/plugin-transform-react-jsx-source": "^7.27.1",
-        "@rolldown/pluginutils": "1.0.0-beta.32",
-        "@types/babel__core": "^7.20.5",
-        "react-refresh": "^0.17.0"
-      },
-      "engines": {
-        "node": "^20.19.0 || >=22.12.0"
-      },
-      "peerDependencies": {
-        "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
-      }
-    },
-    "node_modules/acorn": {
-      "version": "8.15.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
-      "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
-      }
-    },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true,
-      "license": "Python-2.0"
-    },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "license": "MIT"
-    },
-    "node_modules/axios": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
-      "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
-      "license": "MIT",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.4",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fill-range": "^7.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/browserslist": {
-      "version": "4.25.3",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz",
-      "integrity": "sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "caniuse-lite": "^1.0.30001735",
-        "electron-to-chromium": "^1.5.204",
-        "node-releases": "^2.0.19",
-        "update-browserslist-db": "^1.1.3"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      },
-      "engines": {
-        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      }
-    },
-    "node_modules/call-bind-apply-helpers": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
-      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/caniuse-lite": {
-      "version": "1.0.30001737",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz",
-      "integrity": "sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "CC-BY-4.0"
-    },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/chownr": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
-      "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/clsx": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
-      "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "license": "MIT",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/convert-source-map": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
-      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/cookie": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
-      "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/cross-spawn": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
-      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/csstype": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
-      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
-      "devOptional": true,
-      "license": "MIT"
-    },
-    "node_modules/d3-array": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
-      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
-      "license": "ISC",
-      "dependencies": {
-        "internmap": "1 - 2"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-color": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
-      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-ease": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
-      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-format": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
-      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-interpolate": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
-      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
-      "license": "ISC",
-      "dependencies": {
-        "d3-color": "1 - 3"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-path": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
-      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-scale": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
-      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
-      "license": "ISC",
-      "dependencies": {
-        "d3-array": "2.10.0 - 3",
-        "d3-format": "1 - 3",
-        "d3-interpolate": "1.2.0 - 3",
-        "d3-time": "2.1.1 - 3",
-        "d3-time-format": "2 - 4"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-shape": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
-      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
-      "license": "ISC",
-      "dependencies": {
-        "d3-path": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-time": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
-      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
-      "license": "ISC",
-      "dependencies": {
-        "d3-array": "2 - 3"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-time-format": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
-      "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
-      "license": "ISC",
-      "dependencies": {
-        "d3-time": "1 - 3"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/d3-timer": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
-      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/debug": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
-      "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/decimal.js-light": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
-      "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
-      "license": "MIT"
-    },
-    "node_modules/deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/detect-libc": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
-      "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dunder-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
-      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.2.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/electron-to-chromium": {
-      "version": "1.5.208",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.208.tgz",
-      "integrity": "sha512-ozZyibehoe7tOhNaf16lKmljVf+3npZcJIEbJRVftVsmAg5TeA1mGS9dVCZzOwr2xT7xK15V0p7+GZqSPgkuPg==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/enhanced-resolve": {
-      "version": "5.18.3",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
-      "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.4",
-        "tapable": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/es-define-property": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
-      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-errors": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
-      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-object-atoms": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
-      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-set-tostringtag": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
-      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.6",
-        "has-tostringtag": "^1.0.2",
-        "hasown": "^2.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-toolkit": {
-      "version": "1.39.10",
-      "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz",
-      "integrity": "sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==",
-      "license": "MIT",
-      "workspaces": [
-        "docs",
-        "benchmarks"
-      ]
-    },
-    "node_modules/esbuild": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
-      "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.25.9",
-        "@esbuild/android-arm": "0.25.9",
-        "@esbuild/android-arm64": "0.25.9",
-        "@esbuild/android-x64": "0.25.9",
-        "@esbuild/darwin-arm64": "0.25.9",
-        "@esbuild/darwin-x64": "0.25.9",
-        "@esbuild/freebsd-arm64": "0.25.9",
-        "@esbuild/freebsd-x64": "0.25.9",
-        "@esbuild/linux-arm": "0.25.9",
-        "@esbuild/linux-arm64": "0.25.9",
-        "@esbuild/linux-ia32": "0.25.9",
-        "@esbuild/linux-loong64": "0.25.9",
-        "@esbuild/linux-mips64el": "0.25.9",
-        "@esbuild/linux-ppc64": "0.25.9",
-        "@esbuild/linux-riscv64": "0.25.9",
-        "@esbuild/linux-s390x": "0.25.9",
-        "@esbuild/linux-x64": "0.25.9",
-        "@esbuild/netbsd-arm64": "0.25.9",
-        "@esbuild/netbsd-x64": "0.25.9",
-        "@esbuild/openbsd-arm64": "0.25.9",
-        "@esbuild/openbsd-x64": "0.25.9",
-        "@esbuild/openharmony-arm64": "0.25.9",
-        "@esbuild/sunos-x64": "0.25.9",
-        "@esbuild/win32-arm64": "0.25.9",
-        "@esbuild/win32-ia32": "0.25.9",
-        "@esbuild/win32-x64": "0.25.9"
-      }
-    },
-    "node_modules/escalade": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
-      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint": {
-      "version": "9.34.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz",
-      "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.2.0",
-        "@eslint-community/regexpp": "^4.12.1",
-        "@eslint/config-array": "^0.21.0",
-        "@eslint/config-helpers": "^0.3.1",
-        "@eslint/core": "^0.15.2",
-        "@eslint/eslintrc": "^3.3.1",
-        "@eslint/js": "9.34.0",
-        "@eslint/plugin-kit": "^0.3.5",
-        "@humanfs/node": "^0.16.6",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@humanwhocodes/retry": "^0.4.2",
-        "@types/estree": "^1.0.6",
-        "@types/json-schema": "^7.0.15",
-        "ajv": "^6.12.4",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.6",
-        "debug": "^4.3.2",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^8.4.0",
-        "eslint-visitor-keys": "^4.2.1",
-        "espree": "^10.4.0",
-        "esquery": "^1.5.0",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^8.0.0",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "ignore": "^5.2.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.3"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://eslint.org/donate"
-      },
-      "peerDependencies": {
-        "jiti": "*"
-      },
-      "peerDependenciesMeta": {
-        "jiti": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/eslint-plugin-react-hooks": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
-      "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
-      }
-    },
-    "node_modules/eslint-plugin-react-refresh": {
-      "version": "0.4.20",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz",
-      "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "eslint": ">=8.40"
-      }
-    },
-    "node_modules/eslint-scope": {
-      "version": "8.4.0",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
-      "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint-visitor-keys": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
-      "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/espree": {
-      "version": "10.4.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
-      "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "acorn": "^8.15.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^4.2.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/esquery": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
-      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "estraverse": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/eventemitter3": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
-      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
-      "license": "MIT"
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
-      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.8"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fast-glob/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fastq": {
-      "version": "1.19.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
-      "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/file-entry-cache": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
-      "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "flat-cache": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
-      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/flat-cache": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
-      "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "flatted": "^3.2.9",
-        "keyv": "^4.5.4"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/flatted": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
-      "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.11",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
-      "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
-      "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "es-set-tostringtag": "^2.1.0",
-        "hasown": "^2.0.2",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
-      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/gensync": {
-      "version": "1.0.0-beta.2",
-      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
-      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/get-intrinsic": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
-      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.2",
-        "es-define-property": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "es-object-atoms": "^1.1.1",
-        "function-bind": "^1.1.2",
-        "get-proto": "^1.0.1",
-        "gopd": "^1.2.0",
-        "has-symbols": "^1.1.0",
-        "hasown": "^2.0.2",
-        "math-intrinsics": "^1.1.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/get-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
-      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-      "license": "MIT",
-      "dependencies": {
-        "dunder-proto": "^1.0.1",
-        "es-object-atoms": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/globals": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
-      "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/gopd": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
-      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/graceful-fs": {
-      "version": "4.2.11",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-      "license": "ISC"
-    },
-    "node_modules/graphemer": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
-      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
-      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
-      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
-      "license": "MIT",
-      "dependencies": {
-        "has-symbols": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/hasown": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
-      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-      "license": "MIT",
-      "dependencies": {
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ignore": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
-      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/immer": {
-      "version": "10.1.3",
-      "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz",
-      "integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==",
-      "license": "MIT",
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/immer"
-      }
-    },
-    "node_modules/import-fresh": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
-      "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8.19"
-      }
-    },
-    "node_modules/internmap": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
-      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/jiti": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
-      "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
-      "license": "MIT",
-      "bin": {
-        "jiti": "lib/jiti-cli.mjs"
-      }
-    },
-    "node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/jsesc": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
-      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "jsesc": "bin/jsesc"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/json-buffer": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
-      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json5": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "json5": "lib/cli.js"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/keyv": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
-      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "json-buffer": "3.0.1"
-      }
-    },
-    "node_modules/levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/lightningcss": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
-      "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
-      "license": "MPL-2.0",
-      "dependencies": {
-        "detect-libc": "^2.0.3"
-      },
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      },
-      "optionalDependencies": {
-        "lightningcss-darwin-arm64": "1.30.1",
-        "lightningcss-darwin-x64": "1.30.1",
-        "lightningcss-freebsd-x64": "1.30.1",
-        "lightningcss-linux-arm-gnueabihf": "1.30.1",
-        "lightningcss-linux-arm64-gnu": "1.30.1",
-        "lightningcss-linux-arm64-musl": "1.30.1",
-        "lightningcss-linux-x64-gnu": "1.30.1",
-        "lightningcss-linux-x64-musl": "1.30.1",
-        "lightningcss-win32-arm64-msvc": "1.30.1",
-        "lightningcss-win32-x64-msvc": "1.30.1"
-      }
-    },
-    "node_modules/lightningcss-darwin-arm64": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
-      "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-darwin-x64": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
-      "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-freebsd-x64": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
-      "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-linux-arm-gnueabihf": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
-      "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-linux-arm64-gnu": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
-      "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-linux-arm64-musl": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
-      "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-linux-x64-gnu": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
-      "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-linux-x64-musl": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
-      "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-win32-arm64-msvc": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
-      "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/lightningcss-win32-x64-msvc": {
-      "version": "1.30.1",
-      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
-      "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-locate": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lodash.merge": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
-      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/lru-cache": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
-      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^3.0.2"
-      }
-    },
-    "node_modules/magic-string": {
-      "version": "0.30.18",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
-      "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.5.5"
-      }
-    },
-    "node_modules/math-intrinsics": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
-      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
-      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "license": "MIT",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/minipass": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/minizlib": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
-      "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
-      "license": "MIT",
-      "dependencies": {
-        "minipass": "^7.1.2"
-      },
-      "engines": {
-        "node": ">= 18"
-      }
-    },
-    "node_modules/mkdirp": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
-      "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
-      "license": "MIT",
-      "bin": {
-        "mkdirp": "dist/cjs/src/bin.js"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.11",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
-      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/node-releases": {
-      "version": "2.0.19",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
-      "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/optionator": {
-      "version": "0.9.4",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
-      "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.5"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "callsites": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/picocolors": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
-      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
-      "license": "ISC"
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.5.6",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
-      "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "nanoid": "^3.3.11",
-        "picocolors": "^1.1.1",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/prelude-ls": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/proxy-from-env": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
-      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
-      "license": "MIT"
-    },
-    "node_modules/punycode": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
-      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT"
-    },
-    "node_modules/react": {
-      "version": "19.1.1",
-      "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
-      "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/react-dom": {
-      "version": "19.1.1",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
-      "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
-      "license": "MIT",
-      "dependencies": {
-        "scheduler": "^0.26.0"
-      },
-      "peerDependencies": {
-        "react": "^19.1.1"
-      }
-    },
-    "node_modules/react-hook-form": {
-      "version": "7.62.0",
-      "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
-      "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/react-hook-form"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17 || ^18 || ^19"
-      }
-    },
-    "node_modules/react-is": {
-      "version": "19.1.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz",
-      "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==",
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/react-redux": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
-      "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/use-sync-external-store": "^0.0.6",
-        "use-sync-external-store": "^1.4.0"
-      },
-      "peerDependencies": {
-        "@types/react": "^18.2.25 || ^19",
-        "react": "^18.0 || ^19",
-        "redux": "^5.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "redux": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-refresh": {
-      "version": "0.17.0",
-      "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
-      "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/react-router": {
-      "version": "7.8.2",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz",
-      "integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==",
-      "license": "MIT",
-      "dependencies": {
-        "cookie": "^1.0.1",
-        "set-cookie-parser": "^2.6.0"
-      },
-      "engines": {
-        "node": ">=20.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=18",
-        "react-dom": ">=18"
-      },
-      "peerDependenciesMeta": {
-        "react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-router-dom": {
-      "version": "7.8.2",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz",
-      "integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==",
-      "license": "MIT",
-      "dependencies": {
-        "react-router": "7.8.2"
-      },
-      "engines": {
-        "node": ">=20.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=18",
-        "react-dom": ">=18"
-      }
-    },
-    "node_modules/recharts": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.1.2.tgz",
-      "integrity": "sha512-vhNbYwaxNbk/IATK0Ki29k3qvTkGqwvCgyQAQ9MavvvBwjvKnMTswdbklJpcOAoMPN/qxF3Lyqob0zO+ZXkZ4g==",
-      "license": "MIT",
-      "dependencies": {
-        "@reduxjs/toolkit": "1.x.x || 2.x.x",
-        "clsx": "^2.1.1",
-        "decimal.js-light": "^2.5.1",
-        "es-toolkit": "^1.39.3",
-        "eventemitter3": "^5.0.1",
-        "immer": "^10.1.1",
-        "react-redux": "8.x.x || 9.x.x",
-        "reselect": "5.1.1",
-        "tiny-invariant": "^1.3.3",
-        "use-sync-external-store": "^1.2.2",
-        "victory-vendor": "^37.0.2"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
-      }
-    },
-    "node_modules/redux": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
-      "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
-      "license": "MIT"
-    },
-    "node_modules/redux-thunk": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
-      "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "redux": "^5.0.0"
-      }
-    },
-    "node_modules/reselect": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
-      "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
-      "license": "MIT"
-    },
-    "node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/reusify": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
-      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "4.48.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.1.tgz",
-      "integrity": "sha512-jVG20NvbhTYDkGAty2/Yh7HK6/q3DGSRH4o8ALKGArmMuaauM9kLfoMZ+WliPwA5+JHr2lTn3g557FxBV87ifg==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "1.0.8"
-      },
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=18.0.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.48.1",
-        "@rollup/rollup-android-arm64": "4.48.1",
-        "@rollup/rollup-darwin-arm64": "4.48.1",
-        "@rollup/rollup-darwin-x64": "4.48.1",
-        "@rollup/rollup-freebsd-arm64": "4.48.1",
-        "@rollup/rollup-freebsd-x64": "4.48.1",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.48.1",
-        "@rollup/rollup-linux-arm-musleabihf": "4.48.1",
-        "@rollup/rollup-linux-arm64-gnu": "4.48.1",
-        "@rollup/rollup-linux-arm64-musl": "4.48.1",
-        "@rollup/rollup-linux-loongarch64-gnu": "4.48.1",
-        "@rollup/rollup-linux-ppc64-gnu": "4.48.1",
-        "@rollup/rollup-linux-riscv64-gnu": "4.48.1",
-        "@rollup/rollup-linux-riscv64-musl": "4.48.1",
-        "@rollup/rollup-linux-s390x-gnu": "4.48.1",
-        "@rollup/rollup-linux-x64-gnu": "4.48.1",
-        "@rollup/rollup-linux-x64-musl": "4.48.1",
-        "@rollup/rollup-win32-arm64-msvc": "4.48.1",
-        "@rollup/rollup-win32-ia32-msvc": "4.48.1",
-        "@rollup/rollup-win32-x64-msvc": "4.48.1",
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/scheduler": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
-      "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
-      "license": "MIT"
-    },
-    "node_modules/semver": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/set-cookie-parser": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
-      "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
-      "license": "MIT"
-    },
-    "node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
-      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/tailwindcss": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz",
-      "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==",
-      "license": "MIT"
-    },
-    "node_modules/tapable": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
-      "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
-    "node_modules/tar": {
-      "version": "7.4.3",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
-      "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
-      "license": "ISC",
-      "dependencies": {
-        "@isaacs/fs-minipass": "^4.0.0",
-        "chownr": "^3.0.0",
-        "minipass": "^7.1.2",
-        "minizlib": "^3.0.1",
-        "mkdirp": "^3.0.1",
-        "yallist": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tar/node_modules/yallist": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
-      "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tiny-invariant": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
-      "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
-      "license": "MIT"
-    },
-    "node_modules/tinyglobby": {
-      "version": "0.2.14",
-      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
-      "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "fdir": "^6.4.4",
-        "picomatch": "^4.0.2"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/SuperchupuDev"
-      }
-    },
-    "node_modules/tinyglobby/node_modules/fdir": {
-      "version": "6.5.0",
-      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
-      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "peerDependencies": {
-        "picomatch": "^3 || ^4"
-      },
-      "peerDependenciesMeta": {
-        "picomatch": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/tinyglobby/node_modules/picomatch": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
-      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/ts-api-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
-      "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.12"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4"
-      }
-    },
-    "node_modules/type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "prelude-ls": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.8.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
-      "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/typescript-eslint": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.40.0.tgz",
-      "integrity": "sha512-Xvd2l+ZmFDPEt4oj1QEXzA4A2uUK6opvKu3eGN9aGjB8au02lIVcLyi375w94hHyejTOmzIU77L8ol2sRg9n7Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/eslint-plugin": "8.40.0",
-        "@typescript-eslint/parser": "8.40.0",
-        "@typescript-eslint/typescript-estree": "8.40.0",
-        "@typescript-eslint/utils": "8.40.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/update-browserslist-db": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
-      "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "escalade": "^3.2.0",
-        "picocolors": "^1.1.1"
-      },
-      "bin": {
-        "update-browserslist-db": "cli.js"
-      },
-      "peerDependencies": {
-        "browserslist": ">= 4.21.0"
-      }
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/use-sync-external-store": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
-      "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
-      }
-    },
-    "node_modules/victory-vendor": {
-      "version": "37.3.6",
-      "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
-      "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==",
-      "license": "MIT AND ISC",
-      "dependencies": {
-        "@types/d3-array": "^3.0.3",
-        "@types/d3-ease": "^3.0.0",
-        "@types/d3-interpolate": "^3.0.1",
-        "@types/d3-scale": "^4.0.2",
-        "@types/d3-shape": "^3.1.0",
-        "@types/d3-time": "^3.0.0",
-        "@types/d3-timer": "^3.0.0",
-        "d3-array": "^3.1.6",
-        "d3-ease": "^3.0.1",
-        "d3-interpolate": "^3.0.1",
-        "d3-scale": "^4.0.2",
-        "d3-shape": "^3.1.0",
-        "d3-time": "^3.0.0",
-        "d3-timer": "^3.0.1"
-      }
-    },
-    "node_modules/vite": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz",
-      "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==",
-      "license": "MIT",
-      "dependencies": {
-        "esbuild": "^0.25.0",
-        "fdir": "^6.5.0",
-        "picomatch": "^4.0.3",
-        "postcss": "^8.5.6",
-        "rollup": "^4.43.0",
-        "tinyglobby": "^0.2.14"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^20.19.0 || >=22.12.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.3"
-      },
-      "peerDependencies": {
-        "@types/node": "^20.19.0 || >=22.12.0",
-        "jiti": ">=1.21.0",
-        "less": "^4.0.0",
-        "lightningcss": "^1.21.0",
-        "sass": "^1.70.0",
-        "sass-embedded": "^1.70.0",
-        "stylus": ">=0.54.8",
-        "sugarss": "^5.0.0",
-        "terser": "^5.16.0",
-        "tsx": "^4.8.1",
-        "yaml": "^2.4.2"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "jiti": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "sass-embedded": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        },
-        "tsx": {
-          "optional": true
-        },
-        "yaml": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vite/node_modules/fdir": {
-      "version": "6.5.0",
-      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
-      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "peerDependencies": {
-        "picomatch": "^3 || ^4"
-      },
-      "peerDependenciesMeta": {
-        "picomatch": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vite/node_modules/picomatch": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
-      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/word-wrap": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
-      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/zod": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.1.tgz",
-      "integrity": "sha512-SgMZK/h8Tigt9nnKkfJMvB/mKjiJXaX26xegP4sa+0wHIFVFWVlsQGdhklDmuargBD3Hsi3rsQRIzwJIhTPJHA==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/colinhacks"
-      }
-    }
-  }
-}
Index: ontend/package.json
===================================================================
--- frontend/package.json	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,37 +1,0 @@
-{
-  "name": "tasty-tabs-admin",
-  "private": true,
-  "version": "0.0.0",
-  "type": "module",
-  "scripts": {
-    "dev": "vite",
-    "build": "tsc -b && vite build",
-    "lint": "eslint .",
-    "preview": "vite preview"
-  },
-  "dependencies": {
-    "@hookform/resolvers": "^5.2.1",
-    "@tailwindcss/vite": "^4.1.12",
-    "axios": "^1.11.0",
-    "react": "^19.1.1",
-    "react-dom": "^19.1.1",
-    "react-hook-form": "^7.62.0",
-    "react-router-dom": "^7.8.2",
-    "recharts": "^3.1.2",
-    "tailwindcss": "^4.1.12",
-    "zod": "^4.1.1"
-  },
-  "devDependencies": {
-    "@eslint/js": "^9.33.0",
-    "@types/react": "^19.1.10",
-    "@types/react-dom": "^19.1.7",
-    "@vitejs/plugin-react": "^5.0.0",
-    "eslint": "^9.33.0",
-    "eslint-plugin-react-hooks": "^5.2.0",
-    "eslint-plugin-react-refresh": "^0.4.20",
-    "globals": "^16.3.0",
-    "typescript": "~5.8.3",
-    "typescript-eslint": "^8.39.1",
-    "vite": "^7.1.2"
-  }
-}
Index: ontend/public/vite.svg
===================================================================
--- frontend/public/vite.svg	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,1 +1,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
Index: ontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,96 +1,0 @@
-// src/App.tsx
-import { BrowserRouter, Routes, Route, Outlet } from 'react-router-dom';
-import { AuthProvider } from './context/AuthContext';
-import { ROLES } from './utils/roles';
-
-// Layouts
-import { Navbar as AdminNavbar } from './components/Navbar';
-import { PublicNavbar } from './components/public/PublicNavbar';
-
-// Common Pages
-import { LoginPage } from './pages/LoginPage';
-import { ProtectedRoute } from './components/ProtectedRoute';
-
-// Admin Pages
-import DashboardPage from './pages/DashboardPage';
-import { OrdersPage } from './pages/OrdersPage';
-import { OrderDetailsPage } from './pages/OrderDetailsPage';
-import { ReservationsPage as AdminReservationsPage } from './pages/ReservationsPage';
-import { CategoriesPage } from './pages/CategoriesPage';
-import { ProductsPage } from './pages/ProductsPage';
-import { ShiftsPage } from './pages/ShiftsPage';
-import { EmployeesPage } from './pages/EmployeesPage';
-import { AssignmentsPage } from './pages/AssignmentsPage';
-
-// Public Pages
-import { RegisterPage } from './pages/public/RegisterPage';
-import { MenuPage } from './pages/public/MenuPage';
-import { MyReservationsPage } from './pages/public/MyReservationsPage';
-import { MyOrdersPage } from './pages/public/MyOrdersPage';
-import { AnalyticsPage } from './pages/AnalyticsPage';
-
-// Admin Layout
-const AdminLayout = () => (
-    <div className="bg-gray-50 min-h-screen">
-        <AdminNavbar />
-        <main><Outlet /></main>
-    </div>
-);
-
-// Public Layout
-const PublicLayout = () => (
-    <div>
-        <PublicNavbar />
-        <main><Outlet /></main>
-    </div>
-);
-
-function App() {
-    return (
-        <AuthProvider>
-            <BrowserRouter>
-                <Routes>
-                    {/* Public Routes */}
-                    <Route element={<PublicLayout />}>
-                        <Route path="/" element={<MenuPage />} />
-                        <Route path="/login" element={<LoginPage />} />
-                        <Route path="/register" element={<RegisterPage />} />
-                        <Route path="/my-orders" element={<ProtectedRoute allowedRoles={[ROLES.CUSTOMER, ROLES.MANAGER, ROLES.USER]} />}>
-                            <Route index element={<MyOrdersPage />} />
-                        </Route>
-                        <Route path="/my-reservations" element={<ProtectedRoute allowedRoles={[ROLES.CUSTOMER, ROLES.MANAGER, ROLES.USER]} />}>
-                            <Route index element={<MyReservationsPage />} />
-                        </Route>
-                    </Route>
-
-                    {/* Admin Routes */}
-                    <Route path="/admin" element={<AdminLayout />}>
-                        <Route path="" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER, ROLES.FRONT_STAFF, ROLES.BACK_STAFF]} />}>
-                            <Route index element={<DashboardPage />} />
-                        </Route>
-                        <Route path="analytics" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}>
-                            <Route index element={<AnalyticsPage />} />
-                        </Route>
-
-                        <Route path="orders" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER, ROLES.FRONT_STAFF, ROLES.BACK_STAFF]} />}>
-                            <Route index element={<OrdersPage />} />
-                            <Route path=":orderId" element={<OrderDetailsPage />} />
-                        </Route>
-                        <Route path="reservations" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER, ROLES.FRONT_STAFF]} />}>
-                            <Route index element={<AdminReservationsPage />} />
-                        </Route>
-                        <Route path="categories" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}><Route index element={<CategoriesPage />} /></Route>
-                        <Route path="products" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}><Route index element={<ProductsPage />} /></Route>
-                        <Route path="shifts" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}><Route index element={<ShiftsPage />} /></Route>
-                        <Route path="employees" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}><Route index element={<EmployeesPage />} /></Route>
-                        <Route path="assignments" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}><Route index element={<AssignmentsPage />} /></Route>
-                    </Route>
-
-                    <Route path="*" element={<div>404 Not Found</div>} />
-                </Routes>
-            </BrowserRouter>
-        </AuthProvider>
-    );
-}
-
-export default App;
Index: ontend/src/api/analyticsRepository.ts
===================================================================
--- frontend/src/api/analyticsRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,105 +1,0 @@
-// src/api/analyticsRepository.ts
-import axiosClient from "./axiosClient";
-import type {
-  DailyOpsDto,
-  TopProductDto,
-  ServerPerformanceDto,
-  ManagerShiftAboveAvgDto,
-  MonthlyRevenueVsLaborDto,
-  RevenueSplitDto,
-  AnalyticsByChannelResponse,
-} from "../types/api";
-
-const getISODateString = (date: Date) => date.toISOString().split("T")[0];
-
-export const analyticsRepository = {
-  /**
-   * Fetches daily operational summary for the last X days.
-   * @param days The number of past days to include (default 30).
-   */
-  getDailyOps: async (days: number = 30): Promise<DailyOpsDto[]> => {
-    const { data } = await axiosClient.get("/analytics/daily-ops", {
-      params: { days },
-    });
-    return data;
-  },
-
-  /**
-   * Fetches the top-selling products.
-   * @param days The number of past days to analyze (default 90).
-   * @param limit The number of products to return (default 10).
-   */
-  getTopProducts: async (
-    days: number = 90,
-    limit: number = 5,
-  ): Promise<TopProductDto[]> => {
-    const { data } = await axiosClient.get("/analytics/top-products", {
-      params: { days, limit },
-    });
-    return data;
-  },
-
-  /**
-   * Fetches performance metrics for all servers.
-   */
-  getServerPerformance: async (): Promise<ServerPerformanceDto[]> => {
-    const { data } = await axiosClient.get("/analytics/servers/performance");
-    return data;
-  },
-
-  /**
-   * Fetches revenue split between different order types (e.g., ONLINE, TAB) for a date range.
-   */
-  getRevenueSplit: async (): Promise<RevenueSplitDto[]> => {
-    const to = new Date();
-    const from = new Date();
-    from.setDate(to.getDate() - 30); // Default to last 30 days
-
-    const params = { from: getISODateString(from), to: getISODateString(to) };
-    const { data } = await axiosClient.get("/analytics/revenue-split", {
-      params,
-    });
-    return data;
-  },
-
-  /**
-   * Fetches a monthly comparison of total revenue vs. total labor cost.
-   */
-  getMonthlyRevenueVsLabor: async (): Promise<MonthlyRevenueVsLaborDto[]> => {
-    const { data } = await axiosClient.get(
-      "/analytics/monthly-revenue-vs-labor",
-    );
-    return data;
-  },
-
-  /**
-   * Fetches shifts managed by managers that performed above the monthly average.
-   */
-  getManagersShiftsAboveAvg: async (): Promise<ManagerShiftAboveAvgDto[]> => {
-    const { data } = await axiosClient.get(
-      "/analytics/managers/shifts-above-avg",
-    );
-    return data;
-  },
-
-  /**
-   * Fetches revenue grouped by shift periods (e.g., Morning, Afternoon, Evening).
-   * The backend returns a generic structure that we will handle dynamically.
-   */
-  getRevenueByShiftPeriod: async (): Promise<Record<string, any>[]> => {
-    const { data } = await axiosClient.get(
-      "/analytics/revenue-by-shift-period",
-    );
-    return data;
-  },
-
-  getRevenueByChannel: async (params: {
-    from: string;
-    to: string;
-  }): Promise<AnalyticsByChannelResponse> => {
-    const { data } = await axiosClient.get("/analytics/reveunueByChannel", {
-      params,
-    });
-    return data;
-  },
-};
Index: ontend/src/api/assignmentRepository.ts
===================================================================
--- frontend/src/api/assignmentRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,37 +1,0 @@
-// src/api/assignmentRepository.ts
-import axiosClient from "./axiosClient";
-import type { AssignmentDto, CreateAssignmentDto } from "../types/api";
-
-export const assignmentRepository = {
-  getAllAssignments: async (): Promise<AssignmentDto[]> => {
-    const { data } = await axiosClient.get("/assignments");
-    return data;
-  },
-  createAssignment: async (
-    assignmentData: CreateAssignmentDto,
-  ): Promise<AssignmentDto> => {
-    const { data } = await axiosClient.post("/assignments", assignmentData);
-    return data;
-  },
-  // New method to get an employee's next shift
-  getNextShift: async (employeeId: number): Promise<AssignmentDto> => {
-    const { data } = await axiosClient.get(
-      `/employees/${employeeId}/shifts/next`,
-    );
-    return data;
-  },
-  // New method for clocking in
-  clockIn: async (assignmentId: number): Promise<AssignmentDto> => {
-    const { data } = await axiosClient.post(
-      `/assignments/${assignmentId}/clockin`,
-    );
-    return data;
-  },
-  // New method for clocking out
-  clockOut: async (assignmentId: number): Promise<AssignmentDto> => {
-    const { data } = await axiosClient.post(
-      `/assignments/${assignmentId}/clockout`,
-    );
-    return data;
-  },
-};
Index: ontend/src/api/authRepository.ts
===================================================================
--- frontend/src/api/authRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,15 +1,0 @@
-// src/api/authRepository.ts
-import axiosClient from "./axiosClient";
-import type { AuthRequest, AuthDto, RegisterRequest } from "../types/api";
-
-export const authRepository = {
-  login: async (credentials: AuthRequest): Promise<AuthDto> => {
-    const { data } = await axiosClient.post("/auth/login", credentials);
-    return data;
-  },
-  // New method for customer registration
-  register: async (registerData: RegisterRequest): Promise<AuthDto> => {
-    const { data } = await axiosClient.post("/auth/register", registerData);
-    return data;
-  },
-};
Index: ontend/src/api/axiosClient.ts
===================================================================
--- frontend/src/api/axiosClient.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,25 +1,0 @@
-// src/api/axiosClient.ts
-import axios from "axios";
-
-const axiosClient = axios.create({
-  baseURL: "http://localhost:8080/api", // Your backend URL
-  headers: {
-    "Content-Type": "application/json",
-  },
-});
-
-// Interceptor to add the auth token to every request
-axiosClient.interceptors.request.use(
-  (config) => {
-    const token = localStorage.getItem("authToken");
-    if (token) {
-      config.headers.Authorization = `Bearer ${token}`;
-    }
-    return config;
-  },
-  (error) => {
-    return Promise.reject(error);
-  },
-);
-
-export default axiosClient;
Index: ontend/src/api/categoryRepository.ts
===================================================================
--- frontend/src/api/categoryRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,19 +1,0 @@
-// src/api/categoryRepository.ts
-import axiosClient from "./axiosClient";
-import type { CategoryDto, CreateCategoryDto } from "../types/api";
-
-export const categoryRepository = {
-  getAllCategories: async (): Promise<CategoryDto[]> => {
-    const { data } = await axiosClient.get("/categories");
-    return data;
-  },
-  createCategory: async (
-    categoryData: CreateCategoryDto,
-  ): Promise<CategoryDto> => {
-    const { data } = await axiosClient.post("/categories/add", categoryData);
-    return data;
-  },
-  deleteCategory: async (categoryId: number): Promise<void> => {
-    await axiosClient.delete(`/categories/delete/${categoryId}`);
-  },
-};
Index: ontend/src/api/employeeRepository.ts
===================================================================
--- frontend/src/api/employeeRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,20 +1,0 @@
-// src/api/employeeRepository.ts
-import axiosClient from "./axiosClient";
-import type { EmployeeDto, CreateEmployeeRequest } from "../types/api";
-
-export const employeeRepository = {
-  // As per your instruction, the endpoint is /employees
-  getAllEmployees: async (): Promise<EmployeeDto[]> => {
-    const { data } = await axiosClient.get("/employees");
-    return data;
-  },
-  createEmployee: async (
-    employeeData: CreateEmployeeRequest,
-  ): Promise<EmployeeDto> => {
-    const { data } = await axiosClient.post(
-      "/employees/manager/create",
-      employeeData,
-    );
-    return data;
-  },
-};
Index: ontend/src/api/orderRepository.ts
===================================================================
--- frontend/src/api/orderRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,79 +1,0 @@
-// src/api/orderRepository.ts
-import axiosClient from "./axiosClient";
-// Add CreateOrderItemDto to imports
-import type {
-  OrderDto,
-  CreateOrderDto,
-  CreateOrderItemDto,
-  OrderItemDto,
-} from "../types/api";
-
-// Helper to convert existing order items to the format needed for the update payload
-const mapOrderItemsToCreateDto = (
-  items: OrderItemDto[],
-): CreateOrderItemDto[] => {
-  return items.map((item) => ({
-    product_id: item.product_id,
-    quantity: item.quantity,
-    price: item.price,
-    is_processed: item.is_processed,
-  }));
-};
-
-export const orderRepository = {
-  getOpenOrders: async (): Promise<OrderDto[]> => {
-    const { data } = await axiosClient.get("/orders/open");
-    return data;
-  },
-  createOnlineOrder: async (orderData: CreateOrderDto): Promise<OrderDto> => {
-    const { data } = await axiosClient.post("/orders/online", orderData);
-    return data;
-  },
-  getOnlineOrdersByCustomer: async (
-    customerId: number,
-  ): Promise<OrderDto[]> => {
-    const { data } = await axiosClient.get(
-      `/orders/online/customer/${customerId}`,
-    );
-    return data;
-  },
-  // New method to get a single order
-  getOrderById: async (orderId: number): Promise<OrderDto> => {
-    const { data } = await axiosClient.get(`/orders/${orderId}`);
-    return data;
-  },
-  createTabOrder: async (orderData: CreateOrderDto): Promise<OrderDto> => {
-    const { data } = await axiosClient.post("/orders/tab", orderData);
-    return data;
-  },
-  // New method to add items to an existing order
-  addItemToOrder: async (
-    orderId: number,
-    itemData: CreateOrderItemDto,
-  ): Promise<void> => {
-    // Note: The API docs show adding one item at a time.
-    // If you could add multiple, the payload would be CreateOrderItemDto[]
-    await axiosClient.post(`/orders/${orderId}/items`, itemData);
-  },
-
-  updateOrderStatus: async (orderId: number, status: string): Promise<void> => {
-    // The endpoint expects a raw string, not a JSON object
-    await axiosClient.patch(`/orders/${orderId}/status`, { status });
-  },
-
-  // New method to handle general updates
-  updateOrder: async (order: OrderDto): Promise<OrderDto> => {
-    const updatePayload: CreateOrderDto = {
-      status: order.status,
-      type: order.type,
-      table_number: order.table_number,
-      delivery_address: order.delivery_address,
-      order_items: mapOrderItemsToCreateDto(order.order_items),
-    };
-    const { data } = await axiosClient.put(
-      `/orders/${order.id}`,
-      updatePayload,
-    );
-    return data;
-  },
-};
Index: ontend/src/api/paymentRepository.ts
===================================================================
--- frontend/src/api/paymentRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-// src/api/paymentRepository.ts
-import axiosClient from "./axiosClient";
-import type { CreatePaymentDto } from "../types/api";
-
-export const paymentRepository = {
-  createPayment: async (paymentData: CreatePaymentDto): Promise<any> => {
-    const { data } = await axiosClient.post("/payments", paymentData);
-    return data;
-  },
-};
Index: ontend/src/api/productRepository.ts
===================================================================
--- frontend/src/api/productRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,17 +1,0 @@
-// src/api/productRepository.ts
-import axiosClient from "./axiosClient";
-import type { ProductDto, CreateProductDto } from "../types/api";
-
-export const productRepository = {
-  getAllProducts: async (): Promise<ProductDto[]> => {
-    const { data } = await axiosClient.get("/products");
-    return data;
-  },
-  createProduct: async (productData: CreateProductDto): Promise<ProductDto> => {
-    const { data } = await axiosClient.post("/products/add", productData);
-    return data;
-  },
-  deleteProduct: async (productId: number): Promise<void> => {
-    await axiosClient.delete(`/products/delete/${productId}`);
-  },
-};
Index: ontend/src/api/reservationRepository.ts
===================================================================
--- frontend/src/api/reservationRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,39 +1,0 @@
-// src/api/reservationRepository.ts
-import axiosClient from "./axiosClient";
-// Make sure CreateReservationDto is imported
-import type { ReservationDto, CreateReservationDto } from "../types/api";
-
-export const reservationRepository = {
-  getTodayReservations: async (): Promise<ReservationDto[]> => {
-    const { data } = await axiosClient.get("/reservations");
-    return data;
-  },
-  acceptReservation: async (
-    reservationId: number,
-    tableNumber: number,
-  ): Promise<ReservationDto> => {
-    const { data } = await axiosClient.post(
-      `/reservations/accept/${reservationId}/table/${tableNumber}`,
-    );
-    return data;
-  },
-  // Add this new method
-  createReservation: async (
-    reservationData: CreateReservationDto,
-  ): Promise<ReservationDto> => {
-    const { data } = await axiosClient.post(
-      "/reservations/add",
-      reservationData,
-    );
-    return data;
-  },
-
-  getMyReservations: async (): Promise<ReservationDto[]> => {
-    const { data } = await axiosClient.get("/reservations/myReservations");
-    return data;
-  },
-  // New method to delete/cancel a reservation
-  deleteReservation: async (reservationId: number): Promise<void> => {
-    await axiosClient.delete(`/reservations/delete/${reservationId}`);
-  },
-};
Index: ontend/src/api/shiftRepository.ts
===================================================================
--- frontend/src/api/shiftRepository.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,14 +1,0 @@
-// src/api/shiftRepository.ts
-import axiosClient from "./axiosClient";
-import type { ShiftDto, CreateShiftDto } from "../types/api";
-
-export const shiftRepository = {
-  getAllShifts: async (): Promise<ShiftDto[]> => {
-    const { data } = await axiosClient.get("/shifts");
-    return data;
-  },
-  createShift: async (shiftData: CreateShiftDto): Promise<ShiftDto> => {
-    const { data } = await axiosClient.post("/shifts", shiftData);
-    return data;
-  },
-};
Index: ontend/src/assets/react.svg
===================================================================
--- frontend/src/assets/react.svg	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,1 +1,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
Index: ontend/src/components/AddItemModal.tsx
===================================================================
--- frontend/src/components/AddItemModal.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,144 +1,0 @@
-// src/components/modals/AddItemModal.tsx
-import { useEffect, useState } from 'react';
-import type { CategoryDto, ProductDto, CreateOrderItemDto } from '../types/api';
-import { categoryRepository } from '../api/categoryRepository';
-import { productRepository } from '../api/productRepository';
-import { orderRepository } from '../api/orderRepository';
-import { Modal } from './Modal';
-
-interface CartItem extends ProductDto {
-    quantity: number;
-}
-
-interface AddItemModalProps {
-    isOpen: boolean;
-    onClose: () => void;
-    orderId: number;
-    onSuccess: () => void; // To refresh the order details page
-}
-
-export const AddItemModal = ({ isOpen, onClose, orderId, onSuccess }: AddItemModalProps) => {
-    const [view, setView] = useState<'categories' | 'products'>('categories');
-    const [categories, setCategories] = useState<CategoryDto[]>([]);
-    const [products, setProducts] = useState<ProductDto[]>([]);
-    const [selectedCategory, setSelectedCategory] = useState<CategoryDto | null>(null);
-    const [cart, setCart] = useState<Record<number, CartItem>>({});
-    const [isSubmitting, setIsSubmitting] = useState(false);
-
-    useEffect(() => {
-        if (isOpen) {
-            // Reset state when modal opens
-            setView('categories');
-            setCart({});
-            categoryRepository.getAllCategories().then(setCategories).catch(console.error);
-        }
-    }, [isOpen]);
-
-    const handleCategorySelect = (category: CategoryDto) => {
-        setSelectedCategory(category);
-        // You might need a productRepository.getProductsByCategoryId(category.id) method here.
-        // For now, we'll filter the full product list.
-        productRepository.getAllProducts().then(allProducts => {
-            const filteredProducts = allProducts.filter(p => p.category.id === category.id);
-            setProducts(filteredProducts);
-            setView('products');
-        }).catch(console.error);
-    };
-
-    const updateCart = (product: ProductDto, change: 1 | -1) => {
-        setCart(prevCart => {
-            const existingItem = prevCart[product.id];
-            const newQuantity = (existingItem?.quantity || 0) + change;
-
-            if (newQuantity <= 0) {
-                const { [product.id]: _, ...rest } = prevCart;
-                return rest;
-            }
-
-            return {
-                ...prevCart,
-                [product.id]: { ...product, quantity: newQuantity },
-            };
-        });
-    };
-
-    const handleBackToCategories = () => {
-        setView('categories');
-        setSelectedCategory(null);
-    };
-
-    const handleSubmitItems = async () => {
-        setIsSubmitting(true);
-        try {
-            const itemsToAdd: CreateOrderItemDto[] = Object.values(cart).map(item => ({
-                product_id: item.id,
-                quantity: item.quantity,
-                price: item.price, // Price might be determined by the backend
-                is_processed: false,
-            }));
-
-            // The API adds one item at a time, so we must loop.
-            // A batch endpoint would be more efficient here.
-            for (const item of itemsToAdd) {
-                await orderRepository.addItemToOrder(orderId, item);
-            }
-
-            onSuccess();
-            onClose();
-        } catch (error) {
-            console.error("Failed to add items:", error);
-            alert("An error occurred while adding items.");
-        } finally {
-            setIsSubmitting(false);
-        }
-    };
-
-    const cartTotal = Object.values(cart).reduce((sum, item) => sum + item.price * item.quantity, 0);
-
-    return (
-        <Modal isOpen={isOpen} onClose={onClose} title={view === 'categories' ? 'Select a Category' : `Products in ${selectedCategory?.name}`}>
-            <div className="min-h-[400px]">
-                {view === 'products' && (
-                    <button onClick={handleBackToCategories} className="mb-4 text-sm text-blue-600 hover:underline">&larr; Back to Categories</button>
-                )}
-
-                {view === 'categories' && (
-                    <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
-                        {categories.filter(c => c.is_available).map(cat => (
-                            <button key={cat.id} onClick={() => handleCategorySelect(cat)} className="p-4 bg-gray-100 hover:bg-blue-100 rounded-lg text-center font-semibold">
-                                {cat.name}
-                            </button>
-                        ))}
-                    </div>
-                )}
-
-                {view === 'products' && (
-                    <div className="space-y-3">
-                        {products.map(prod => (
-                            <div key={prod.id} className="flex justify-between items-center p-2 border rounded-lg">
-                                <div>
-                                    <p className="font-semibold">{prod.name}</p>
-                                    <p className="text-sm text-gray-600">${prod.price.toFixed(2)}</p>
-                                </div>
-                                <div className="flex items-center space-x-3">
-                                    <button onClick={() => updateCart(prod, -1)} className="bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center font-bold">-</button>
-                                    <span>{cart[prod.id]?.quantity || 0}</span>
-                                    <button onClick={() => updateCart(prod, 1)} className="bg-green-500 text-white rounded-full w-6 h-6 flex items-center justify-center font-bold">+</button>
-                                </div>
-                            </div>
-                        ))}
-                    </div>
-                )}
-            </div>
-
-            {Object.keys(cart).length > 0 && (
-                <div className="mt-4 pt-4 border-t flex justify-between items-center">
-                    <p className="font-semibold">Total: ${cartTotal.toFixed(2)}</p>
-                    <button onClick={handleSubmitItems} disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                        {isSubmitting ? 'Adding...' : `Add ${Object.values(cart).reduce((sum, item) => sum + item.quantity, 0)} Items`}
-                    </button>
-                </div>
-            )}
-        </Modal>
-    );
-};
Index: ontend/src/components/Modal.tsx
===================================================================
--- frontend/src/components/Modal.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,26 +1,0 @@
-// src/components/Modal.tsx
-import { type ReactNode } from 'react';
-
-interface ModalProps {
-    isOpen: boolean;
-    onClose: () => void;
-    title: string;
-    children: ReactNode;
-}
-
-export const Modal = ({ isOpen, onClose, title, children }: ModalProps) => {
-    if (!isOpen) return null;
-
-    return (
-        <div className="fixed inset-0 bg-opacity-50 z-50 flex justify-center items-center">
-            <div className="fixed inset-0 bg-black opacity-50" onClick={onClose}></div>
-            <div className="bg-white rounded-lg shadow-xl p-6 w-full max-w-lg relative">
-                <div className="flex justify-between items-center border-b pb-3 mb-4">
-                    <h3 className="text-xl font-semibold">{title}</h3>
-                    <button onClick={onClose} className="text-black close-modal text-2xl font-bold">&times;</button>
-                </div>
-                <div>{children}</div>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/Navbar.tsx
===================================================================
--- frontend/src/components/Navbar.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,68 +1,0 @@
-// src/components/Navbar.tsx
-import { NavLink, useNavigate } from 'react-router-dom';
-import { useAuth } from '../hooks/useAuth';
-import { ROLE_PERMISSIONS } from '../utils/roles';
-
-const navLinks = [
-    { path: '/admin/orders', label: 'Orders' },
-    { path: '/admin/reservations', label: 'Reservations' },
-    { path: '/admin/categories', label: 'Categories' }, // New
-    { path: '/admin/products', label: 'Products' }, // New
-    { path: '/admin/shifts', label: 'Shifts' },
-    { path: '/admin/employees', label: 'Employees' },
-    { path: '/admin/assignments', label: 'Assignments' },
-    { path: '/admin/analytics', label: 'Analytics' }, // New Link
-];
-
-
-
-export const Navbar = () => {
-    const { isAuthenticated, logout, user } = useAuth();
-    const navigate = useNavigate();
-
-    const handleLogout = () => {
-        logout();
-        navigate('/login');
-    };
-
-    const availableLinks = isAuthenticated && user
-        ? navLinks.filter(link => ROLE_PERMISSIONS[user.user_type]?.includes(link.path))
-        : [];
-
-    return (
-        <nav className="bg-gray-800 text-white p-4 flex justify-between items-center">
-            <div className="flex items-center space-x-6">
-                <NavLink to="/admin" className="text-xl font-bold">TastyTabs</NavLink>
-                <div className="flex space-x-4">
-                    {isAuthenticated && availableLinks.map(link => (
-                        <NavLink
-                            key={link.path}
-                            to={link.path}
-                            className={({ isActive }) =>
-                                `px-3 py-2 rounded-md text-sm font-medium ${isActive ? 'bg-gray-900' : 'hover:bg-gray-700'
-                                }`
-                            }
-                        >
-                            {link.label}
-                        </NavLink>
-                    ))}
-                </div>
-            </div>
-            <div className="flex items-center space-x-4">
-                {isAuthenticated && user && (
-                    <span className="text-sm">Welcome, {user.email}</span>
-                    // TODO: Display current shift info here
-                )}
-                {isAuthenticated ? (
-                    <button onClick={handleLogout} className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
-                        Logout
-                    </button>
-                ) : (
-                    <button onClick={() => navigate('/login')} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                        Login
-                    </button>
-                )}
-            </div>
-        </nav>
-    );
-};
Index: ontend/src/components/ProtectedRoute.tsx
===================================================================
--- frontend/src/components/ProtectedRoute.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-// src/components/ProtectedRoute.tsx
-import { Navigate, Outlet } from 'react-router-dom';
-import { useAuth } from '../hooks/useAuth';
-import { UserType } from '../types/api';
-
-interface ProtectedRouteProps {
-    allowedRoles: UserType[];
-}
-
-export const ProtectedRoute = ({ allowedRoles }: ProtectedRouteProps) => {
-    const { isAuthenticated, isLoading, hasRole } = useAuth();
-
-    if (isLoading) {
-        return <div>Loading...</div>; // Or a spinner component
-    }
-
-    if (!isAuthenticated) {
-        return <Navigate to="/login" replace />;
-    }
-
-    if (!hasRole(allowedRoles)) {
-        console.log("Access denied. User does not have the required role.");
-        return <Navigate to="/" replace />; // Or a dedicated "Unauthorized" page
-    }
-
-    return <Outlet />;
-};
Index: ontend/src/components/analytics/ManagerPerformanceTable.tsx
===================================================================
--- frontend/src/components/analytics/ManagerPerformanceTable.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,48 +1,0 @@
-// src/components/analytics/ManagerPerformanceTable.tsx
-import { useEffect, useState } from 'react';
-import type { ManagerShiftAboveAvgDto } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-export const ManagerPerformanceTable = () => {
-    const [data, setData] = useState<ManagerShiftAboveAvgDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getManagersShiftsAboveAvg()
-            .then(setData)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading manager performance...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md">
-            <h3 className="text-xl font-semibold mb-4">Manager Shifts Above Average Revenue</h3>
-            <div className="overflow-x-auto">
-                <table className="min-w-full">
-                    <thead>
-                        <tr>
-                            <th className="py-2 text-left">Manager</th>
-                            <th className="py-2 text-left">Shift Date</th>
-                            <th className="py-2 text-left">Shift Time</th>
-                            <th className="py-2 text-right">Shift Revenue</th>
-                            <th className="py-2 text-right">Average Revenue</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {data.map((shift, i) => (
-                            <tr key={i} className="border-t">
-                                <td className="py-2">{shift.manager_email}</td>
-                                <td className="py-2">{new Date(shift.shift_date).toLocaleDateString()}</td>
-                                <td className="py-2">{shift.shift_start_time} - {shift.shift_end_time}</td>
-                                <td className="py-2 text-right font-bold text-green-600">${shift.shift_revenue.toFixed(2)}</td>
-                                <td className="py-2 text-right text-gray-600">${shift.avg_revenue_per_shift.toFixed(2)}</td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/analytics/MonthlyRevenueLaborChart.tsx
===================================================================
--- frontend/src/components/analytics/MonthlyRevenueLaborChart.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,36 +1,0 @@
-// src/components/analytics/MonthlyRevenueLaborChart.tsx
-import { useEffect, useState } from 'react';
-import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
-import type { MonthlyRevenueVsLaborDto } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-export const MonthlyRevenueLaborChart = () => {
-    const [data, setData] = useState<MonthlyRevenueVsLaborDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getMonthlyRevenueVsLabor()
-            .then(setData)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading monthly performance...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md h-[400px]">
-            <h3 className="text-xl font-semibold mb-4">Monthly Revenue vs. Labor Cost</h3>
-            <ResponsiveContainer width="100%" height="90%">
-                <BarChart data={data}>
-                    <CartesianGrid strokeDasharray="3 3" />
-                    <XAxis dataKey="period" />
-                    <YAxis />
-                    <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
-                    <Legend />
-                    <Bar dataKey="total_revenue" fill="#8884d8" name="Revenue" />
-                    <Bar dataKey="total_labor_cost" fill="#82ca9d" name="Labor Cost" />
-                </BarChart>
-            </ResponsiveContainer>
-        </div>
-    );
-};
Index: ontend/src/components/analytics/RevenueByChannelChart.tsx
===================================================================
--- frontend/src/components/analytics/RevenueByChannelChart.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,118 +1,0 @@
-// src/components/analytics/RevenueByChannelChart.tsx
-import { useEffect, useState, useMemo, useCallback } from 'react';
-import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
-import type { AnalyticsByChannelResponse } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-// Helper to get date strings for API params
-const getISODateString = (date: Date) => date.toISOString().split('T')[0];
-
-const COLORS = ['#8884d8', '#82ca9d', '#ffc658', '#FF8042'];
-
-export const RevenueByChannelChart = () => {
-    const [data, setData] = useState<AnalyticsByChannelResponse | null>(null);
-    const [loading, setLoading] = useState(true);
-
-    // State for the date inputs
-    const [dateRange, setDateRange] = useState(() => {
-        const to = new Date();
-        const from = new Date();
-        from.setDate(to.getDate() - 29); // Default to last 30 days
-        return {
-            from: getISODateString(from),
-            to: getISODateString(to),
-        };
-    });
-
-    const fetchData = useCallback(() => {
-        setLoading(true);
-        analyticsRepository.getRevenueByChannel(dateRange)
-            .then(setData)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, [dateRange]);
-
-    // Fetch data on initial load and when the date range is submitted
-    useEffect(() => {
-        fetchData();
-    }, [dateRange, fetchData]);
-
-    // Transform the API data into a format that Recharts can easily use for a multi-line chart.
-    const chartData = useMemo(() => {
-        if (!data) return [];
-
-        const processedData: Record<string, any> = {};
-        const channels = data.channels.map(c => c.channel);
-
-        data.channels.forEach(channel => {
-            channel.data.forEach(dailyData => {
-                if (!processedData[dailyData.day]) {
-                    processedData[dailyData.day] = { day: dailyData.day };
-                    // Initialize other channels to 0 for this day to keep the lines continuous
-                    channels.forEach(c => { processedData[dailyData.day][c] = 0; });
-                }
-                processedData[dailyData.day][channel.channel] = dailyData.revenue;
-            });
-        });
-
-        // Sort data by date to ensure the X-axis is chronological
-        return Object.values(processedData).sort((a, b) => new Date(a.day).getTime() - new Date(b.day).getTime());
-    }, [data]);
-
-    const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-        setDateRange(prev => ({ ...prev, [e.target.name]: e.target.value }));
-    };
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md">
-            <div className="md:flex justify-between items-center mb-4">
-                <h3 className="text-xl font-semibold mb-2 md:mb-0">Revenue by Channel</h3>
-                <div className="flex items-center gap-2">
-                    <input type="date" name="from" value={dateRange.from} onChange={handleDateChange} className="p-1 border rounded" />
-                    <span>to</span>
-                    <input type="date" name="to" value={dateRange.to} onChange={handleDateChange} className="p-1 border rounded" />
-                </div>
-            </div>
-
-            {loading ? <p>Loading chart data...</p> : (
-                <div className="h-[400px]">
-                    <ResponsiveContainer width="100%" height="100%">
-                        <LineChart data={chartData}>
-                            <CartesianGrid strokeDasharray="3 3" />
-                            <XAxis dataKey="day" tickFormatter={(dateStr) => new Date(dateStr).toLocaleDateString([], { month: 'short', day: 'numeric' })} />
-                            <YAxis tickFormatter={(value) => `$${value}`} />
-                            <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
-                            <Legend />
-                            {data?.channels.map((channel, index) => (
-                                <Line
-                                    key={channel.channel}
-                                    type="monotone"
-                                    dataKey={channel.channel}
-                                    stroke={COLORS[index % COLORS.length]}
-                                    strokeWidth={2}
-                                    dot={false}
-                                />
-                            ))}
-                        </LineChart>
-                    </ResponsiveContainer>
-                </div>
-            )}
-            {data && (
-                <div className="grid grid-cols-3 gap-4 text-center mt-4 border-t pt-4">
-                    <div>
-                        <p className="text-sm text-gray-500">Grand Total Revenue</p>
-                        <p className="text-xl font-bold">${data.grand_total_revenue.toLocaleString(undefined, { minimumFractionDigits: 2 })}</p>
-                    </div>
-                    <div>
-                        <p className="text-sm text-gray-500">Total Paid Orders</p>
-                        <p className="text-xl font-bold">{data.grand_total_paid_orders.toLocaleString()}</p>
-                    </div>
-                    <div>
-                        <p className="text-sm text-gray-500">Total Tips</p>
-                        <p className="text-xl font-bold">${data.grand_total_tips.toLocaleString(undefined, { minimumFractionDigits: 2 })}</p>
-                    </div>
-                </div>
-            )}
-        </div>
-    );
-};
Index: ontend/src/components/analytics/RevenueByShiftPeriodTable.tsx
===================================================================
--- frontend/src/components/analytics/RevenueByShiftPeriodTable.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,51 +1,0 @@
-// src/components/analytics/RevenueByShiftPeriodTable.tsx
-import { useEffect, useState } from 'react';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-export const RevenueByShiftPeriodTable = () => {
-    const [data, setData] = useState<Record<string, any>[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [headers, setHeaders] = useState<string[]>([]);
-
-    useEffect(() => {
-        analyticsRepository.getRevenueByShiftPeriod()
-            .then(rawData => {
-                if (rawData.length > 0) {
-                    setHeaders(Object.keys(rawData[0]));
-                }
-                setData(rawData);
-            })
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading revenue by shift period...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md">
-            <h3 className="text-xl font-semibold mb-4">Revenue by Shift Period</h3>
-            <div className="overflow-x-auto">
-                <table className="min-w-full">
-                    <thead>
-                        <tr>
-                            {headers.map(header => (
-                                <th key={header} className="py-2 text-left capitalize">{header.replace(/_/g, ' ')}</th>
-                            ))}
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {data.map((row, i) => (
-                            <tr key={i} className="border-t">
-                                {headers.map(header => (
-                                    <td key={header} className="py-2">
-                                        {typeof row[header] === 'number' ? `$${row[header].toFixed(2)}` : row[header]}
-                                    </td>
-                                ))}
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    )
-};
Index: ontend/src/components/analytics/RevenueSplitChart.tsx
===================================================================
--- frontend/src/components/analytics/RevenueSplitChart.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,47 +1,0 @@
-// src/components/analytics/RevenueSplitChart.tsx
-import { useEffect, useState } from 'react';
-import { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer } from 'recharts';
-import type { RevenueSplitDto } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
-
-export const RevenueSplitChart = () => {
-    const [data, setData] = useState<RevenueSplitDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getRevenueSplit()
-            .then(setData)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading revenue split...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md h-[400px]">
-            <h3 className="text-xl font-semibold mb-4">Revenue by Order Type (Last 30 Days)</h3>
-            <ResponsiveContainer width="100%" height="100%">
-                <PieChart>
-                    <Pie
-                        data={data}
-                        dataKey="total_revenue"
-                        nameKey="order_type"
-                        cx="50%"
-                        cy="50%"
-                        outerRadius={120}
-                        fill="#8884d8"
-                        label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
-                    >
-                        {data.map((entry, index) => (
-                            <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
-                        ))}
-                    </Pie>
-                    <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
-                    <Legend />
-                </PieChart>
-            </ResponsiveContainer>
-        </div>
-    );
-};
Index: ontend/src/components/analytics/ServerPerformanceTable.tsx
===================================================================
--- frontend/src/components/analytics/ServerPerformanceTable.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,46 +1,0 @@
-// src/components/analytics/ServerPerformanceTable.tsx
-import { useEffect, useState } from 'react';
-import type { ServerPerformanceDto } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-export const ServerPerformanceTable = () => {
-    const [servers, setServers] = useState<ServerPerformanceDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getServerPerformance()
-            .then(setServers)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading server performance...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md">
-            <h3 className="text-xl font-semibold mb-4">Server Performance</h3>
-            <div className="overflow-x-auto">
-                <table className="min-w-full leading-normal">
-                    <thead>
-                        <tr>
-                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Server</th>
-                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Orders Processed</th>
-                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Avg. Order Value</th>
-                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Total Revenue</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {servers.map(server => (
-                            <tr key={server.server_email}>
-                                <td className="px-5 py-4 border-b text-sm">{server.server_email}</td>
-                                <td className="px-5 py-4 border-b text-sm">{server.orders_processed}</td>
-                                <td className="px-5 py-4 border-b text-sm">${server.avg_order_value.toFixed(2)}</td>
-                                <td className="px-5 py-4 border-b text-sm font-bold">${server.total_revenue_generated.toFixed(2)}</td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/analytics/StatCard.tsx
===================================================================
--- frontend/src/components/analytics/StatCard.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,20 +1,0 @@
-// src/components/analytics/StatCard.tsx
-import type { ReactNode } from 'react';
-
-interface StatCardProps {
-    title: string;
-    value: string | number;
-    icon: ReactNode;
-}
-
-export const StatCard = ({ title, value, icon }: StatCardProps) => (
-    <div className="bg-white p-4 rounded-lg shadow-md flex items-center">
-        <div className="bg-blue-100 text-blue-600 rounded-full p-3 mr-4">
-            {icon}
-        </div>
-        <div>
-            <p className="text-sm text-gray-500">{title}</p>
-            <p className="text-2xl font-bold">{value}</p>
-        </div>
-    </div>
-);
Index: ontend/src/components/analytics/TopProductsList.tsx
===================================================================
--- frontend/src/components/analytics/TopProductsList.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,38 +1,0 @@
-// src/components/analytics/TopProductsList.tsx
-import { useEffect, useState } from 'react';
-import type { TopProductDto } from '../../types/api';
-import { analyticsRepository } from '../../api/analyticsRepository';
-
-export const TopProductsList = () => {
-    const [products, setProducts] = useState<TopProductDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getTopProducts(90, 5)
-            .then(setProducts)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    if (loading) return <p>Loading top products...</p>;
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md">
-            <h3 className="text-xl font-semibold mb-4">Top Selling Products (Last 90 Days)</h3>
-            <ul className="space-y-3">
-                {products.map(product => (
-                    <li key={product.product_name} className="flex justify-between items-center border-b pb-2">
-                        <div>
-                            <p className="font-semibold">{product.product_name}</p>
-                            <p className="text-sm text-gray-500">{product.category_name}</p>
-                        </div>
-                        <div className="text-right">
-                            <p className="font-bold">${product.total_revenue.toFixed(2)}</p>
-                            <p className="text-sm text-gray-500">{product.total_quantity_sold} sold</p>
-                        </div>
-                    </li>
-                ))}
-            </ul>
-        </div>
-    );
-};
Index: ontend/src/components/employee/CurrentShiftCard.tsx
===================================================================
--- frontend/src/components/employee/CurrentShiftCard.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,130 +1,0 @@
-// src/components/employee/CurrentShiftCard.tsx
-import { useEffect, useState } from 'react';
-import type { AssignmentDto } from '../../types/api';
-import { assignmentRepository } from '../../api/assignmentRepository';
-import { useAuth } from '../../hooks/useAuth';
-
-export const CurrentShiftCard = () => {
-    const { user } = useAuth();
-    const [assignment, setAssignment] = useState<AssignmentDto | null>(null);
-    const [loading, setLoading] = useState(true);
-    const [error, setError] = useState('');
-    const [isActionLoading, setIsActionLoading] = useState(false);
-
-    useEffect(() => {
-        if (user) {
-            assignmentRepository.getNextShift(user.id)
-                .then(setAssignment)
-                .catch(() => setError('No upcoming shift found.'))
-                .finally(() => setLoading(false));
-        }
-    }, [user]);
-
-    const handleClockIn = async () => {
-        if (!assignment) return;
-        setIsActionLoading(true);
-        try {
-            const updatedAssignment = await assignmentRepository.clockIn(assignment.id);
-            setAssignment(updatedAssignment);
-        } catch (err) {
-            alert('Failed to clock in.');
-            console.error(err);
-        } finally {
-            setIsActionLoading(false);
-        }
-    };
-
-    const handleClockOut = async () => {
-        if (!assignment) return;
-        setIsActionLoading(true);
-        try {
-            const updatedAssignment = await assignmentRepository.clockOut(assignment.id);
-            setAssignment(updatedAssignment);
-        } catch (err) {
-            alert('Failed to clock out.');
-            console.error(err);
-        } finally {
-            setIsActionLoading(false);
-        }
-    };
-
-    const formatTime = (dateString?: string) => {
-        if (!dateString) return 'N/A';
-        return new Date(dateString).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
-    };
-
-    if (loading) return <div>Loading your shift details...</div>;
-    if (error) return <div className="text-center text-gray-500">{error}</div>;
-    if (!assignment) return null;
-
-    const { shift, manager, clock_in_time, clock_out_time } = assignment;
-    const shiftStartTime = new Date(shift.start);
-    const now = new Date();
-    const oneHourBeforeShift = new Date(shiftStartTime.getTime() - 60 * 60 * 1000);
-
-    const isClockInDisabled = now < oneHourBeforeShift;
-    const isClockedIn = !!clock_in_time && !clock_out_time;
-    const isShiftComplete = !!clock_in_time && !!clock_out_time;
-
-    const getActionButton = () => {
-        if (isShiftComplete) {
-            return <p className="text-center font-semibold text-green-600">Shift Completed</p>;
-        }
-        if (isClockedIn) {
-            return (
-                <button
-                    onClick={handleClockOut}
-                    disabled={isActionLoading}
-                    className="w-full bg-red-500 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg disabled:bg-gray-400"
-                >
-                    {isActionLoading ? 'Processing...' : 'Clock Out'}
-                </button>
-            );
-        }
-        return (
-            <button
-                onClick={handleClockIn}
-                disabled={isClockInDisabled || isActionLoading}
-                className="w-full bg-green-500 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-lg disabled:bg-gray-400"
-                title={isClockInDisabled ? `You can clock in after ${formatTime(oneHourBeforeShift.toISOString())}` : ''}
-            >
-                {isActionLoading ? 'Processing...' : 'Clock In'}
-            </button>
-        );
-    };
-
-    return (
-        <div className="bg-white p-6 rounded-lg shadow-md max-w-md mx-auto">
-            <h2 className="text-2xl font-bold text-center mb-1">Your Next Shift</h2>
-            <p className="text-center text-gray-500 mb-4">{new Date(shift.date).toLocaleDateString([], { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}</p>
-
-            <div className="grid grid-cols-2 gap-4 text-center my-6">
-                <div>
-                    <p className="text-sm text-gray-500">Shift Starts</p>
-                    <p className="text-xl font-bold">{formatTime(shift.start)}</p>
-                </div>
-                <div>
-                    <p className="text-sm text-gray-500">Shift Ends</p>
-                    <p className="text-xl font-bold">{formatTime(shift.end)}</p>
-                </div>
-                <div>
-                    <p className="text-sm text-gray-500">Clocked In</p>
-                    <p className={`text-xl font-bold ${clock_in_time ? 'text-green-600' : ''}`}>{formatTime(clock_in_time)}</p>
-                </div>
-                <div>
-                    <p className="text-sm text-gray-500">Clocked Out</p>
-                    <p className={`text-xl font-bold ${clock_out_time ? 'text-red-600' : ''}`}>{formatTime(clock_out_time)}</p>
-                </div>
-            </div>
-
-            <div className="text-center mb-6">
-                <p className="text-sm text-gray-500">Manager</p>
-                <p className="text-lg font-semibold">{manager.email}</p>
-            </div>
-
-            <div className="mt-4">
-                {getActionButton()}
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/forms/AcceptReservationForm.tsx
===================================================================
--- frontend/src/components/forms/AcceptReservationForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,59 +1,0 @@
-// src/components/forms/AcceptReservationForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { reservationRepository } from '../../api/reservationRepository';
-
-const acceptReservationSchema = z.object({
-    table_number: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Table number is required')
-    ),
-});
-
-type AcceptReservationFormData = z.infer<typeof acceptReservationSchema>;
-
-interface AcceptReservationFormProps {
-    reservationId: number;
-    onSuccess: () => void;
-}
-
-export const AcceptReservationForm = ({ reservationId, onSuccess }: AcceptReservationFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<AcceptReservationFormData>({
-        resolver: zodResolver(acceptReservationSchema),
-    });
-
-    const onSubmit = async (data: AcceptReservationFormData) => {
-        try {
-            await reservationRepository.acceptReservation(reservationId, data.table_number);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to accept reservation:', error);
-            alert('Failed to accept reservation. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)}>
-            <div className="mb-4">
-                <label htmlFor="table_number" className="block text-sm font-medium text-gray-700">Assign Table Number</label>
-                <input
-                    id="table_number"
-                    type="number"
-                    {...register('table_number')}
-                    className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
-                />
-                {errors.table_number && <p className="text-red-500 text-xs mt-1">{errors.table_number.message}</p>}
-            </div>
-            <div className="flex justify-end">
-                <button
-                    type="submit"
-                    disabled={isSubmitting}
-                    className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:bg-gray-400"
-                >
-                    {isSubmitting ? 'Accepting...' : 'Accept Reservation'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateAssignmentForm.tsx
===================================================================
--- frontend/src/components/forms/CreateAssignmentForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,100 +1,0 @@
-// src/components/forms/CreateAssignmentForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { assignmentRepository } from '../../api/assignmentRepository';
-import { useEffect, useState } from 'react';
-import type { EmployeeDto, ShiftDto } from '../../types/api';
-import { employeeRepository } from '../../api/employeeRepository';
-import { shiftRepository } from '../../api/shiftRepository';
-
-const createAssignmentSchema = z.object({
-    employee_id: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Please select an employee')
-    ),
-    shift_id: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Please select a shift')
-    ),
-});
-
-type CreateAssignmentFormData = z.infer<typeof createAssignmentSchema>;
-
-interface CreateAssignmentFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateAssignmentForm = ({ onSuccess }: CreateAssignmentFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateAssignmentFormData>({
-        resolver: zodResolver(createAssignmentSchema),
-    });
-
-    const [employees, setEmployees] = useState<EmployeeDto[]>([]);
-    const [shifts, setShifts] = useState<ShiftDto[]>([]);
-
-    useEffect(() => {
-        // Fetch both employees and shifts when the component mounts
-        Promise.all([
-            employeeRepository.getAllEmployees(),
-            shiftRepository.getAllShifts()
-        ]).then(([empData, shiftData]) => {
-            setEmployees(empData);
-            setShifts(shiftData);
-        }).catch(console.error);
-    }, []);
-
-    const onSubmit = async (data: CreateAssignmentFormData) => {
-        try {
-            await assignmentRepository.createAssignment(data);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create assignment:', error);
-            alert('Failed to create assignment. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)}>
-            <div className="mb-4">
-                <label htmlFor="employee_id" className="block text-sm font-medium text-gray-700">Employee</label>
-                <select
-                    id="employee_id"
-                    {...register('employee_id')}
-                    className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
-                >
-                    <option value="">Select Employee</option>
-                    {employees.map(emp => <option key={emp.id} value={emp.id}>{emp.email}</option>)}
-                </select>
-                {errors.employee_id && <p className="text-red-500 text-xs mt-1">{errors.employee_id.message}</p>}
-            </div>
-
-            <div className="mb-4">
-                <label htmlFor="shift_id" className="block text-sm font-medium text-gray-700">Shift</label>
-                <select
-                    id="shift_id"
-                    {...register('shift_id')}
-                    className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
-                >
-                    <option value="">Select Shift</option>
-                    {shifts.map(shift => (
-                        <option key={shift.id} value={shift.id}>
-                            {new Date(shift.date).toLocaleDateString()} ({new Date(shift.start).toLocaleTimeString()} - {new Date(shift.end).toLocaleTimeString()})
-                        </option>
-                    ))}
-                </select>
-                {errors.shift_id && <p className="text-red-500 text-xs mt-1">{errors.shift_id.message}</p>}
-            </div>
-
-            <div className="flex justify-end">
-                <button
-                    type="submit"
-                    disabled={isSubmitting}
-                    className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:bg-gray-400"
-                >
-                    {isSubmitting ? 'Assigning...' : 'Create Assignment'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateCategoryForm.tsx
===================================================================
--- frontend/src/components/forms/CreateCategoryForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,52 +1,0 @@
-// src/components/forms/CreateCategoryForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { categoryRepository } from '../../api/categoryRepository';
-
-const createCategorySchema = z.object({
-    name: z.string().min(2, 'Name must be at least 2 characters'),
-    is_available: z.boolean(),
-});
-
-type CreateCategoryFormData = z.infer<typeof createCategorySchema>;
-
-interface CreateCategoryFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateCategoryForm = ({ onSuccess }: CreateCategoryFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateCategoryFormData>({
-        resolver: zodResolver(createCategorySchema),
-        defaultValues: { is_available: true },
-    });
-
-    const onSubmit = async (data: CreateCategoryFormData) => {
-        try {
-            await categoryRepository.createCategory(data);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create category:', error);
-            alert('Failed to create category.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-            <div>
-                <label>Category Name</label>
-                <input {...register('name')} className="w-full p-2 border rounded" />
-                {errors.name && <p className="text-red-500 text-xs">{errors.name.message}</p>}
-            </div>
-            <div className="flex items-center">
-                <input type="checkbox" {...register('is_available')} className="h-4 w-4 rounded" />
-                <label className="ml-2">Is Available</label>
-            </div>
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Creating...' : 'Create Category'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateEmployeeForm.tsx
===================================================================
--- frontend/src/components/forms/CreateEmployeeForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,108 +1,0 @@
-// src/components/forms/CreateEmployeeForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { employeeRepository } from '../../api/employeeRepository';
-import type { CreateEmployeeRequest } from '../../types/api';
-
-const staffRoles = [
-    { id: 1, name: 'Server' },
-    { id: 2, name: 'Chef' },
-    { id: 3, name: 'Bartender' },
-    { id: 4, name: 'Hostess' },
-];
-
-const createEmployeeSchema = z.object({
-    email: z.string().email('Invalid email address'),
-    password: z.string().min(6, 'Password must be at least 6 characters'),
-    employee_type: z.enum(["MANAGER", "FRONT_STAFF", "BACK_STAFF"]),
-    staff_role_id: z.preprocess(
-        (a) => a ? parseInt(z.string().parse(a), 10) : undefined,
-        z.number().optional()
-    ),
-    phone_number: z.string().optional(),
-    gross_salary: z.number().min(0, 'Gross salary must be non-negative').optional().default(0),
-    net_salary: z.number().min(0, 'Net salary must be non-negative').optional().default(0),
-    // Add other fields from CreateEmployeeRequest as needed
-});
-
-type CreateEmployeeFormData = z.infer<typeof createEmployeeSchema>;
-
-interface CreateEmployeeFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateEmployeeForm = ({ onSuccess }: CreateEmployeeFormProps) => {
-    const { register, handleSubmit, watch, formState: { errors, isSubmitting } } = useForm<CreateEmployeeFormData>({
-        resolver: zodResolver(createEmployeeSchema),
-    });
-
-    const employeeType = watch('employee_type');
-
-    const onSubmit = async (data: CreateEmployeeFormData) => {
-        try {
-            const employeeData: CreateEmployeeRequest = { ...data };
-            await employeeRepository.createEmployee(employeeData);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create employee:', error);
-            alert('Failed to create employee. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-            <div>
-                <label>Email</label>
-                <input {...register('email')} className="w-full p-2 border rounded" />
-                {errors.email && <p className="text-red-500 text-xs">{errors.email.message}</p>}
-            </div>
-            <div>
-                <label>Password</label>
-                <input type="password" {...register('password')} className="w-full p-2 border rounded" />
-                {errors.password && <p className="text-red-500 text-xs">{errors.password.message}</p>}
-            </div>
-            <div>
-                <label>Employee Type</label>
-                <select {...register('employee_type')} className="w-full p-2 border rounded">
-                    <option value="">Select Type</option>
-                    <option value="MANAGER">Manager</option>
-                    <option value="FRONT_STAFF">Front Staff</option>
-                    <option value="BACK_STAFF">Back Staff</option>
-                </select>
-                {errors.employee_type && <p className="text-red-500 text-xs">{errors.employee_type.message}</p>}
-            </div>
-
-            {employeeType !== 'MANAGER' && (
-                <div>
-                    <label>Staff Role</label>
-                    <select {...register('staff_role_id')} className="w-full p-2 border rounded">
-                        <option value="">Select Role</option>
-                        {staffRoles.map(role => <option key={role.id} value={role.id}>{role.name}</option>)}
-                    </select>
-                    {errors.staff_role_id && <p className="text-red-500 text-xs">{errors.staff_role_id.message}</p>}
-                </div>
-            )}
-
-            <div>
-                <label>Phone Number</label>
-                <input {...register('phone_number')} className="w-full p-2 border rounded" />
-            </div>
-            <div>
-                <label>Gross Salary ($)</label>
-                <input type="number" {...register('gross_salary', { valueAsNumber: true })} className="w-full p-2 border rounded" />
-
-            </div>
-            <div>
-                <label>Net Salary ($)</label>
-                <input type="number" {...register('net_salary', { valueAsNumber: true })} className="w-full p-2 border rounded" />
-            </div>
-
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Creating...' : 'Create Employee'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateProductForm.tsx
===================================================================
--- frontend/src/components/forms/CreateProductForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,103 +1,0 @@
-// src/components/forms/CreateProductForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { productRepository } from '../../api/productRepository';
-import { useEffect, useState } from 'react';
-import type { CategoryDto } from '../../types/api';
-import { categoryRepository } from '../../api/categoryRepository';
-
-const createProductSchema = z.object({
-    name: z.string().min(2, 'Name must be at least 2 characters'),
-    price: z.preprocess(
-        (a) => parseFloat(z.string().parse(a)),
-        z.number().positive('Price must be positive')
-    ),
-    // description: z.string().min(10, 'Description must be at least 10 characters'),
-    category_id: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Please select a category')
-    ),
-    tax_class: z.string().default('A'),
-    manage_inventory: z.boolean().default(false),
-    description: z.string().default(''),
-});
-
-type CreateProductFormData = z.infer<typeof createProductSchema>;
-
-interface CreateProductFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateProductForm = ({ onSuccess }: CreateProductFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateProductFormData>({
-        resolver: zodResolver(createProductSchema),
-    });
-
-    const [categories, setCategories] = useState<CategoryDto[]>([]);
-
-    useEffect(() => {
-        categoryRepository.getAllCategories().then(setCategories).catch(console.error);
-    }, []);
-
-    const onSubmit = async (data: CreateProductFormData) => {
-        try {
-            await productRepository.createProduct(data);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create product:', error);
-            alert('Failed to create product.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-            <div>
-                <label>Product Name</label>
-                <input {...register('name')} className="w-full p-2 border rounded" />
-                {errors.name && <p className="text-red-500 text-xs">{errors.name.message}</p>}
-            </div>
-            <div>
-                <label>Price ($)</label>
-                <input type="number" step="0.01" {...register('price')} className="w-full p-2 border rounded" />
-                {errors.price && <p className="text-red-500 text-xs">{errors.price.message}</p>}
-            </div>
-            <div>
-                <label>Category</label>
-                <select {...register('category_id')} className="w-full p-2 border rounded">
-                    <option value="">Select a category</option>
-                    {categories.filter(c => c.is_available).map(cat => (
-                        <option key={cat.id} value={cat.id}>{cat.name}</option>
-                    ))}
-                </select>
-                {errors.category_id && <p className="text-red-500 text-xs">{errors.category_id.message}</p>}
-            </div>
-            <div>
-                <label>Tax Class</label>
-                <select {...register('tax_class')} className="w-full p-2 border rounded">
-                    <option value="A">A - 10%</option>
-                    <option value="B">B - 5%</option>
-                    <option value="C">C - 0%</option>
-                    <option value="D">D - 18%</option>
-                </select>
-                {errors.category_id && <p className="text-red-500 text-xs">{errors.category_id.message}</p>}
-            </div>
-
-            <div>
-                <label>Product Description</label>
-                <textarea {...register('description')} className="w-full p-2 border rounded" />
-                {errors.description && <p className="text-red-500 text-xs">{errors.description.message}</p>}
-            </div>
-
-            <div>
-                <input type="checkbox" {...register('manage_inventory')} className="mr-2" />
-                <label>Manage Inventory</label>
-            </div>
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Creating...' : 'Create Product'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateReservationForm.tsx
===================================================================
--- frontend/src/components/forms/CreateReservationForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,76 +1,0 @@
-// src/components/forms/CreateReservationForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { reservationRepository } from '../../api/reservationRepository';
-import type { CreateReservationDto } from '../../types/api';
-
-const createReservationSchema = z.object({
-    number_of_people: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'At least one person is required')
-    ),
-    stay_length: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(30, 'Minimum stay is 30 minutes')
-    ),
-    date: z.string().min(1, 'Date is required'),
-    time: z.string().min(1, 'Time is required'),
-});
-
-type CreateReservationFormData = z.infer<typeof createReservationSchema>;
-
-interface CreateReservationFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateReservationForm = ({ onSuccess }: CreateReservationFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateReservationFormData>({
-        resolver: zodResolver(createReservationSchema),
-    });
-
-    const onSubmit = async (data: CreateReservationFormData) => {
-        try {
-            const reservationData: CreateReservationDto = {
-                number_of_people: data.number_of_people,
-                stay_length: data.stay_length,
-                datetime: `${data.date}T${data.time}:00`,
-            };
-            await reservationRepository.createReservation(reservationData);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create reservation:', error);
-            alert('Failed to create reservation. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-            <div>
-                <label>Number of People</label>
-                <input type="number" {...register('number_of_people')} className="w-full p-2 border rounded" />
-                {errors.number_of_people && <p className="text-red-500 text-xs">{errors.number_of_people.message}</p>}
-            </div>
-            <div>
-                <label>Stay Length (in minutes)</label>
-                <input type="number" step="15" {...register('stay_length')} className="w-full p-2 border rounded" />
-                {errors.stay_length && <p className="text-red-500 text-xs">{errors.stay_length.message}</p>}
-            </div>
-            <div>
-                <label>Date</label>
-                <input type="date" {...register('date')} className="w-full p-2 border rounded" />
-                {errors.date && <p className="text-red-500 text-xs">{errors.date.message}</p>}
-            </div>
-            <div>
-                <label>Time</label>
-                <input type="time" {...register('time')} className="w-full p-2 border rounded" />
-                {errors.time && <p className="text-red-500 text-xs">{errors.time.message}</p>}
-            </div>
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Creating...' : 'Create Reservation'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateShiftForm.tsx
===================================================================
--- frontend/src/components/forms/CreateShiftForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,64 +1,0 @@
-// src/components/forms/CreateShiftForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { shiftRepository } from '../../api/shiftRepository';
-import type { CreateShiftDto } from '../../types/api';
-
-const createShiftSchema = z.object({
-    date: z.string().min(1, 'Date is required'),
-    startTime: z.string().min(1, 'Start time is required'),
-    endTime: z.string().min(1, 'End time is required'),
-});
-
-type CreateShiftFormData = z.infer<typeof createShiftSchema>;
-
-interface CreateShiftFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateShiftForm = ({ onSuccess }: CreateShiftFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateShiftFormData>({
-        resolver: zodResolver(createShiftSchema),
-    });
-
-    const onSubmit = async (data: CreateShiftFormData) => {
-        try {
-            const shiftData: CreateShiftDto = {
-                date: data.date,
-                start: `${data.date}T${data.startTime}:00`,
-                end: `${data.date}T${data.endTime}:00`,
-            };
-            await shiftRepository.createShift(shiftData);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create shift:', error);
-            alert('Failed to create shift. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-            <div>
-                <label>Date</label>
-                <input type="date" {...register('date')} className="w-full p-2 border rounded" />
-                {errors.date && <p className="text-red-500 text-xs">{errors.date.message}</p>}
-            </div>
-            <div>
-                <label>Start Time</label>
-                <input type="time" {...register('startTime')} className="w-full p-2 border rounded" />
-                {errors.startTime && <p className="text-red-500 text-xs">{errors.startTime.message}</p>}
-            </div>
-            <div>
-                <label>End Time</label>
-                <input type="time" {...register('endTime')} className="w-full p-2 border rounded" />
-                {errors.endTime && <p className="text-red-500 text-xs">{errors.endTime.message}</p>}
-            </div>
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Creating...' : 'Create Shift'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/CreateTabOrderForm.tsx
===================================================================
--- frontend/src/components/forms/CreateTabOrderForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,67 +1,0 @@
-// src/components/forms/CreateTabOrderForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { orderRepository } from '../../api/orderRepository';
-import type { CreateOrderDto } from '../../types/api';
-
-const createOrderSchema = z.object({
-    table_number: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Table number is required')
-    ),
-    // For MVP, we'll create an empty tab. Items can be added later.
-});
-
-type CreateOrderFormData = z.infer<typeof createOrderSchema>;
-
-interface CreateTabOrderFormProps {
-    onSuccess: () => void;
-}
-
-export const CreateTabOrderForm = ({ onSuccess }: CreateTabOrderFormProps) => {
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<CreateOrderFormData>({
-        resolver: zodResolver(createOrderSchema),
-    });
-
-    const onSubmit = async (data: CreateOrderFormData) => {
-        try {
-            const newOrderData: CreateOrderDto = {
-                table_number: data.table_number,
-                type: 'TAB',
-                status: 'PENDING',
-                order_items: [], // Start with an empty order
-            };
-            await orderRepository.createTabOrder(newOrderData);
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to create tab order:', error);
-            alert('Failed to create tab. Please try again.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)}>
-            <div className="mb-4">
-                <label htmlFor="table_number" className="block text-sm font-medium text-gray-700">Table Number</label>
-                <input
-                    id="table_number"
-                    type="number"
-                    {...register('table_number')}
-                    className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
-                />
-                {errors.table_number && <p className="text-red-500 text-xs mt-1">{errors.table_number.message}</p>}
-            </div>
-
-            <div className="flex justify-end">
-                <button
-                    type="submit"
-                    disabled={isSubmitting}
-                    className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:bg-gray-400"
-                >
-                    {isSubmitting ? 'Creating...' : 'Create Tab'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/forms/UpdateTableNumberForm.tsx
===================================================================
--- frontend/src/components/forms/UpdateTableNumberForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,52 +1,0 @@
-// src/components/forms/UpdateTableNumberForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import type { OrderDto } from '../../types/api';
-import { orderRepository } from '../../api/orderRepository';
-
-const updateTableSchema = z.object({
-    table_number: z.preprocess(
-        (a) => parseInt(z.string().parse(a), 10),
-        z.number().min(1, 'Invalid table number')
-    ),
-});
-
-type UpdateTableFormData = z.infer<typeof updateTableSchema>;
-
-interface UpdateTableNumberFormProps {
-    order: OrderDto;
-    onSuccess: () => void;
-}
-
-export const UpdateTableNumberForm = ({ order, onSuccess }: UpdateTableNumberFormProps) => {
-    const { register, handleSubmit, formState: { isSubmitting } } = useForm<UpdateTableFormData>({
-        resolver: zodResolver(updateTableSchema),
-        defaultValues: { table_number: order.table_number },
-    });
-
-    const onSubmit = async (data: UpdateTableFormData) => {
-        try {
-            const updatedOrderData = { ...order, table_number: data.table_number };
-            await orderRepository.updateOrder(updatedOrderData);
-            alert('Table number updated successfully!');
-            onSuccess();
-        } catch (error) {
-            console.error('Failed to update table number:', error);
-            alert('Failed to update table number.');
-        }
-    };
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)} className="flex items-center space-x-2">
-            <input
-                type="number"
-                {...register('table_number')}
-                className="p-1 border rounded w-20"
-            />
-            <button type="submit" disabled={isSubmitting} className="bg-gray-200 hover:bg-gray-300 text-black text-xs font-bold py-1 px-2 rounded">
-                {isSubmitting ? '...' : 'Save'}
-            </button>
-        </form>
-    );
-};
Index: ontend/src/components/modals/PaymentModal.tsx
===================================================================
--- frontend/src/components/modals/PaymentModal.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,109 +1,0 @@
-// src/components/modals/PaymentModal.tsx
-import { useState, useMemo } from 'react';
-import type { OrderDto, CreatePaymentDto } from '../../types/api';
-import { paymentRepository } from '../../api/paymentRepository';
-import { Modal } from '../Modal';
-
-interface PaymentModalProps {
-    isOpen: boolean;
-    onClose: () => void;
-    order: OrderDto;
-    onSuccess: () => void;
-}
-
-const TIP_OPTIONS = [5, 10, 15];
-
-export const PaymentModal = ({ isOpen, onClose, order, onSuccess }: PaymentModalProps) => {
-    const [paymentType, setPaymentType] = useState<'CASH' | 'CARD' | null>(null);
-    const [tipOption, setTipOption] = useState<number | 'custom' | null>(null);
-    const [customTip, setCustomTip] = useState('');
-    const [isSubmitting, setIsSubmitting] = useState(false);
-    const [error, setError] = useState('');
-
-    const subtotal = useMemo(() =>
-        order.order_items.reduce((sum, item) => sum + (item.price * item.quantity), 0),
-        [order.order_items]
-    );
-
-    const tipAmount = useMemo(() => {
-        if (tipOption === 'custom') {
-            return parseFloat(customTip) || 0;
-        }
-        if (tipOption) {
-            return subtotal * (tipOption / 100);
-        }
-        return 0;
-    }, [tipOption, customTip, subtotal]);
-
-    const total = subtotal + tipAmount;
-
-    const handleSubmit = async () => {
-        setError('');
-        if (!paymentType) {
-            setError('Please select a payment method.');
-            return;
-        }
-
-        setIsSubmitting(true);
-        const paymentData: CreatePaymentDto = {
-            order_id: order.id,
-            amount: total,
-            payment_type: paymentType,
-            tip_amount: tipAmount,
-        };
-
-        try {
-            await paymentRepository.createPayment(paymentData);
-            alert('Payment successful!');
-            onSuccess();
-        } catch (err) {
-            console.error("Payment failed:", err);
-            setError('An error occurred during payment. Please try again.');
-        } finally {
-            setIsSubmitting(false);
-        }
-    };
-
-    return (
-        <Modal isOpen={isOpen} onClose={onClose} title={`Payment for Order #${order.id}`}>
-            <div className="space-y-4">
-                {/* Payment Method */}
-                <div>
-                    <h4 className="font-semibold mb-2">Payment Method</h4>
-                    <div className="flex gap-4">
-                        <button onClick={() => setPaymentType('CASH')} className={`w-full p-3 rounded-lg border-2 ${paymentType === 'CASH' ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}>Cash</button>
-                        <button onClick={() => setPaymentType('CARD')} className={`w-full p-3 rounded-lg border-2 ${paymentType === 'CARD' ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}>Card</button>
-                    </div>
-                </div>
-
-                {/* Tip Selection */}
-                <div>
-                    <h4 className="font-semibold mb-2">Add a Tip</h4>
-                    <div className="flex gap-2">
-                        {TIP_OPTIONS.map(opt => (
-                            <button key={opt} onClick={() => setTipOption(opt)} className={`flex-1 p-2 rounded border ${tipOption === opt ? 'bg-blue-500 text-white' : ''}`}>{opt}%</button>
-                        ))}
-                        <button onClick={() => setTipOption('custom')} className={`flex-1 p-2 rounded border ${tipOption === 'custom' ? 'bg-blue-500 text-white' : ''}`}>Custom</button>
-                    </div>
-                    {tipOption === 'custom' && (
-                        <input type="number" placeholder="Enter tip amount" value={customTip} onChange={e => setCustomTip(e.target.value)} className="w-full mt-2 p-2 border rounded" />
-                    )}
-                </div>
-
-                {/* Summary */}
-                <div className="border-t pt-4 space-y-2">
-                    <div className="flex justify-between"><span className="text-gray-600">Subtotal</span><span>${subtotal.toFixed(2)}</span></div>
-                    <div className="flex justify-between"><span className="text-gray-600">Tip</span><span>${tipAmount.toFixed(2)}</span></div>
-                    <div className="flex justify-between font-bold text-lg"><span >Grand Total</span><span>${total.toFixed(2)}</span></div>
-                </div>
-
-                {error && <p className="text-red-500 text-sm">{error}</p>}
-
-                {/* Action Button */}
-                <button onClick={handleSubmit} disabled={isSubmitting} className="w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 rounded-lg disabled:bg-gray-400">
-                    {isSubmitting ? 'Processing...' : 'Confirm Payment'}
-                </button>
-            </div>
-        </Modal>
-    );
-};
Index: ontend/src/components/order/UpdateOrderStatusActions.tsx
===================================================================
--- frontend/src/components/order/UpdateOrderStatusActions.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,61 +1,0 @@
-// src/components/order/UpdateOrderStatusActions.tsx
-import { useState } from 'react';
-import type { OrderDto } from '../../types/api';
-import { orderRepository } from '../../api/orderRepository';
-
-interface UpdateOrderStatusActionsProps {
-    order: OrderDto;
-    onSuccess: () => void;
-}
-
-const availableStatuses = ["PENDING", "CONFIRMED", "COMPLETED", "CANCELED"];
-
-export const UpdateOrderStatusActions = ({ order, onSuccess }: UpdateOrderStatusActionsProps) => {
-    const [loadingStatus, setLoadingStatus] = useState<string | null>(null);
-
-    const handleChangeStatus = async (newStatus: string) => {
-        setLoadingStatus(newStatus);
-        try {
-            await orderRepository.updateOrderStatus(order.id, newStatus);
-            onSuccess();
-        } catch (error) {
-            console.error(`Failed to update status to ${newStatus}:`, error);
-            alert('Failed to update status.');
-        } finally {
-            setLoadingStatus(null);
-        }
-    };
-
-    // Don't show actions for completed or canceled orders
-    if (order.status === 'COMPLETED' || order.status === 'CANCELED') {
-        return null;
-    }
-
-    return (
-        <div className="mt-4 pt-4">
-            <h3 className="text-md font-semibold mb-2">Actions</h3>
-            <div className="flex flex-wrap gap-2">
-                {availableStatuses.map(status => {
-                    // Don't show a button for the current status
-                    if (status === order.status) return null;
-
-                    return (
-                        <button
-                            key={status}
-                            onClick={() => handleChangeStatus(status)}
-                            disabled={!!loadingStatus}
-                            className={`text-white font-bold py-1 px-3 rounded text-sm disabled:bg-gray-400
-                ${status === 'COMPLETED' ? 'bg-green-500 hover:bg-green-700' : ''}
-                ${status === 'CANCELED' ? 'bg-red-500 hover:bg-red-700' : ''}
-                ${status === 'CONFIRMED' ? 'bg-yellow-500 hover:bg-yellow-600' : ''}
-                ${status === 'PENDING' ? 'bg-blue-500 hover:bg-blue-700' : ''}
-              `}
-                        >
-                            {loadingStatus === status ? 'Updating...' : `Mark as ${status.replace('_', ' ')}`}
-                        </button>
-                    )
-                })}
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/public/CartSidebar.tsx
===================================================================
--- frontend/src/components/public/CartSidebar.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,57 +1,0 @@
-// src/components/public/CartSidebar.tsx
-// src/components/public/CartSidebar.tsx
-import type { ProductDto } from '../../types/api';
-
-interface CartItem extends ProductDto {
-    quantity: number;
-}
-
-interface CartSidebarProps {
-    cart: Record<number, CartItem>;
-    onUpdateQuantity: (product: ProductDto, change: 1 | -1) => void;
-    onCheckout: () => void;
-}
-
-export const CartSidebar = ({ cart, onUpdateQuantity, onCheckout }: CartSidebarProps) => {
-    const cartItems = Object.values(cart);
-    const total = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
-
-    if (cartItems.length === 0) {
-        return (
-            <div className="bg-white p-4 rounded-lg shadow-lg h-full">
-                <h3 className="text-xl font-bold border-b pb-2">Your Order</h3>
-                <p className="text-gray-500 mt-4">Your cart is empty. Add items from the menu to get started!</p>
-            </div>
-        );
-    }
-
-    return (
-        <div className="bg-white p-4 rounded-lg shadow-lg h-full flex flex-col">
-            <h3 className="text-xl font-bold border-b pb-2">Your Order</h3>
-            <div className="flex-grow my-4 space-y-3 overflow-y-auto">
-                {cartItems.map(item => (
-                    <div key={item.id} className="flex justify-between items-center">
-                        <div>
-                            <p className="font-semibold">{item.name}</p>
-                            <p className="text-sm text-gray-600">${item.price.toFixed(2)}</p>
-                        </div>
-                        <div className="flex items-center space-x-2">
-                            <button onClick={() => onUpdateQuantity(item, -1)} className="font-bold">-</button>
-                            <span>{item.quantity}</span>
-                            <button onClick={() => onUpdateQuantity(item, 1)} className="font-bold">+</button>
-                        </div>
-                    </div>
-                ))}
-            </div>
-            <div className="border-t pt-4">
-                <div className="flex justify-between font-bold text-lg mb-4">
-                    <span>Total</span>
-                    <span>${total.toFixed(2)}</span>
-                </div>
-                <button onClick={onCheckout} className="w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 rounded-lg">
-                    Checkout
-                </button>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/components/public/CheckoutForm.tsx
===================================================================
--- frontend/src/components/public/CheckoutForm.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,37 +1,0 @@
-// src/components/forms/CheckoutForm.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-
-const checkoutSchema = z.object({
-    delivery_address: z.string().min(10, 'Please enter a valid address'),
-});
-
-type CheckoutFormData = z.infer<typeof checkoutSchema>;
-
-interface CheckoutFormProps {
-    onSubmit: (data: CheckoutFormData) => void;
-    isSubmitting: boolean;
-}
-
-export const CheckoutForm = ({ onSubmit, isSubmitting }: CheckoutFormProps) => {
-    const { register, handleSubmit, formState: { errors } } = useForm<CheckoutFormData>({
-        resolver: zodResolver(checkoutSchema),
-    });
-
-    return (
-        <form onSubmit={handleSubmit(onSubmit)}>
-            <p className="mb-4">Please provide your delivery address to complete the order.</p>
-            <div className="mb-4">
-                <label>Delivery Address</label>
-                <textarea {...register('delivery_address')} rows={3} className="w-full p-2 border rounded" />
-                {errors.delivery_address && <p className="text-red-500 text-xs">{errors.delivery_address.message}</p>}
-            </div>
-            <div className="flex justify-end">
-                <button type="submit" disabled={isSubmitting} className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
-                    {isSubmitting ? 'Placing Order...' : 'Confirm Order'}
-                </button>
-            </div>
-        </form>
-    );
-};
Index: ontend/src/components/public/PublicNavbar.tsx
===================================================================
--- frontend/src/components/public/PublicNavbar.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,45 +1,0 @@
-// src/components/public/PublicNavbar.tsx
-import { NavLink, useNavigate } from 'react-router-dom';
-import { useAuth } from '../../hooks/useAuth';
-
-export const PublicNavbar = () => {
-    const { isAuthenticated, logout, user } = useAuth();
-    const navigate = useNavigate();
-
-    const handleLogout = () => {
-        logout();
-        navigate('/');
-    };
-
-    return (
-        <nav className="bg-white shadow-md text-gray-800 p-4 flex justify-between items-center">
-            <NavLink to="/" className="text-2xl font-bold text-blue-600">TastyTabs</NavLink>
-            <div className="flex items-center space-x-4">
-                <NavLink to="/" className={({ isActive }) => `hover:text-blue-600 ${isActive ? 'font-semibold' : ''}`}>Menu</NavLink>
-                {isAuthenticated && (
-                    <>
-                        <NavLink to="/my-orders" className={({ isActive }) => `hover:text-blue-600 ${isActive ? 'font-semibold' : ''}`}>My Orders</NavLink>
-                        <NavLink to="/my-reservations" className={({ isActive }) => `hover:text-blue-600 ${isActive ? 'font-semibold' : ''}`}>My Reservations</NavLink>
-                    </>
-                )}
-                {isAuthenticated ? (
-                    <>
-                        <span className="text-sm">Hi, {user?.email}</span>
-                        <button onClick={handleLogout} className="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-3 rounded-md text-sm">
-                            Logout
-                        </button>
-                    </>
-                ) : (
-                    <div className="space-x-2">
-                        <button onClick={() => navigate('/login')} className="bg-gray-200 hover:bg-gray-300 text-black font-bold py-2 px-3 rounded-md text-sm">
-                            Login
-                        </button>
-                        <button onClick={() => navigate('/register')} className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-3 rounded-md text-sm">
-                            Register
-                        </button>
-                    </div>
-                )}
-            </div>
-        </nav>
-    );
-};
Index: ontend/src/components/reservations/ReservationCard.tsx
===================================================================
--- frontend/src/components/reservations/ReservationCard.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,119 +1,0 @@
-import type { ReservationDto, UserDto } from "../../types/api";
-
-const CalendarIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>;
-const ClockIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>;
-const UsersIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>;
-const HourglassIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><path d="M5 22h14" /><path d="M5 2h14" /><path d="M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22" /><path d="M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2" /></svg>;
-const TableIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><path d="M2 10h20" /><path d="M2 16h20" /><path d="M12 2v20" /><path d="M6 2v20" /><path d="M18 2v20" /></svg>;
-const CheckCircleIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5 text-slate-400"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" /><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>;
-const CheckIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>;
-const XIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>;
-
-// Status Badge Component
-const StatusBadge = ({ status }: { status: "PENDING" | "ACCEPTED" | "COMPLETED" | "CANCELLED" }) => {
-    const statusStyles = {
-        PENDING: "bg-amber-100 text-amber-800",
-        ACCEPTED: "bg-sky-100 text-sky-800",
-        COMPLETED: "bg-slate-200 text-slate-800",
-        CANCELLED: "bg-red-100 text-red-800",
-    };
-
-    return (
-        <span className={`px-3 py-1 text-xs font-semibold rounded-full ${statusStyles[status]}`}>
-            {status}
-        </span>
-    );
-};
-
-interface ReservationCardProps {
-    reservation: ReservationDto;
-    user: UserDto | null;
-    onAccept: (reservation: ReservationDto) => void;
-    onDecline: (reservation: ReservationDto) => void;
-}
-
-const ReservationCard = ({ reservation, user, onAccept, onDecline }: ReservationCardProps) => {
-    const {
-        email,
-        datetime,
-        number_of_people,
-        stay_length,
-        status,
-        assigned_table_number,
-        front_staff_name: front_staff_name
-    } = reservation;
-
-    const reservationDate = new Date(datetime);
-    const dateOptions = { year: 'numeric', month: 'long', day: 'numeric' };
-
-    return (
-        <div className="bg-white rounded-xl shadow-md overflow-hidden transform hover:-translate-y-1 hover:shadow-lg transition-all duration-300 flex flex-col">
-            {/* Card Header */}
-            <div className="p-4 md:p-5 border-b border-slate-200 flex justify-between items-start">
-                <h3 className="font-bold text-lg text-slate-800 truncate pr-2" title={email}>{email}</h3>
-                <StatusBadge status={status} />
-            </div>
-
-            {/* Card Body */}
-            <div className="p-4 md:p-5 flex-grow">
-                <div className="grid grid-cols-1 sm:grid-cols-2 gap-y-4 gap-x-2">
-                    <div className="flex items-center space-x-3">
-                        <CalendarIcon />
-                        <span className="text-sm text-slate-600">{reservationDate.toLocaleDateString(undefined, dateOptions)}</span>
-                    </div>
-                    <div className="flex items-center space-x-3">
-                        <ClockIcon />
-                        <span className="text-sm text-slate-600">{reservationDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
-                    </div>
-                    <div className="flex items-center space-x-3">
-                        <UsersIcon />
-                        <span className="text-sm text-slate-600">{number_of_people} Guests</span>
-                    </div>
-                    {stay_length ? <div className="flex items-center space-x-3">
-                        <HourglassIcon />
-                        <span className="text-sm text-slate-600">{stay_length} min{stay_length > 1 ? 's' : ''} stay</span>
-                    </div> : <span className="text-sm text-slate-400 italic">No stay length specified</span>}
-                </div>
-
-                {status === 'ACCEPTED' && (
-                    <div className="mt-4 pt-4 border-t border-slate-200/60 space-y-4">
-                        {assigned_table_number && (
-                            <div className="flex items-center space-x-3">
-                                <TableIcon />
-                                <span className="text-sm text-slate-600 font-medium">Assigned Table: <span className="font-bold text-slate-800">#{assigned_table_number}</span></span>
-                            </div>
-                        )}
-                        {front_staff_name && (
-                            <div className="flex items-center space-x-3">
-                                <CheckCircleIcon />
-                                <span className="text-sm text-slate-600">Accepted by: <span className="font-medium text-slate-800 truncate">{front_staff_name}</span></span>
-                            </div>
-                        )}
-                    </div>
-                )}
-            </div>
-
-            {/* Card Footer with Actions */}
-            {user?.user_type === "FRONT_STAFF" && status === "PENDING" && (
-                <div className="px-4 md:px-5 py-3 bg-slate-50 flex space-x-2 justify-end">
-                    <button
-                        onClick={() => onDecline(reservation)}
-                        className="px-3 py-2 text-sm font-medium text-red-700 bg-red-100 rounded-lg hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors duration-200 flex items-center space-x-1.5"
-                    >
-                        <XIcon />
-                        <span>Decline</span>
-                    </button>
-                    <button
-                        onClick={() => onAccept(reservation)}
-                        className="px-3 py-2 text-sm font-medium text-green-700 bg-green-100 rounded-lg hover:bg-green-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-colors duration-200 flex items-center space-x-1.5"
-                    >
-                        <CheckIcon />
-                        <span>Accept</span>
-                    </button>
-                </div>
-            )}
-        </div>
-    );
-};
-
-export default ReservationCard;
Index: ontend/src/context/AuthContext.tsx
===================================================================
--- frontend/src/context/AuthContext.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,76 +1,0 @@
-// src/context/AuthContext.tsx
-import { createContext, useState, useEffect, type ReactNode } from 'react';
-import { type UserDto, type AuthRequest, UserType } from '../types/api';
-import { authRepository } from '../api/authRepository';
-
-interface AuthContextType {
-    user: UserDto | null;
-    token: string | null;
-    isAuthenticated: boolean;
-    isLoading: boolean;
-    login: (credentials: AuthRequest) => Promise<UserDto>; // Changed return type
-    logout: () => void;
-    hasRole: (roles: UserType[]) => boolean;
-}
-
-const AuthContext = createContext<AuthContextType | undefined>(undefined);
-
-interface AuthProviderProps {
-    children: ReactNode;
-}
-
-export const AuthProvider = ({ children }: AuthProviderProps) => {
-    const [user, setUser] = useState<UserDto | null>(null);
-    const [token, setToken] = useState<string | null>(localStorage.getItem('authToken'));
-    const [isLoading, setIsLoading] = useState(true);
-
-    useEffect(() => {
-        const storedToken = localStorage.getItem('authToken');
-        const storedUser = localStorage.getItem('user');
-
-        if (storedToken && storedUser) {
-            setToken(storedToken);
-            setUser(JSON.parse(storedUser));
-        }
-        setIsLoading(false);
-
-    }, []);
-
-    const login = async (credentials: AuthRequest): Promise<UserDto> => { // Changed return type
-        const response = await authRepository.login(credentials);
-        localStorage.setItem('authToken', response.token);
-        localStorage.setItem('user', JSON.stringify(response.user));
-        setToken(response.token);
-        setUser(response.user);
-        return response.user; // Return the user object
-    };
-
-    const logout = () => {
-        localStorage.removeItem('authToken');
-        localStorage.removeItem('user');
-        setToken(null);
-        setUser(null);
-    };
-
-    const hasRole = (roles: UserType[]): boolean => {
-        console.log("Checking roles:", roles, "for user:", user);
-        return user ? roles.includes(user.user_type) : false;
-    };
-
-    return (
-        <AuthContext.Provider value={{
-            user,
-            token,
-            isAuthenticated: !!token,
-            isLoading,
-            login,
-            logout,
-            hasRole,
-        }}>
-            {children}
-        </AuthContext.Provider>
-    );
-};
-
-export default AuthContext;
-
Index: ontend/src/hooks/useAuth.ts
===================================================================
--- frontend/src/hooks/useAuth.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,11 +1,0 @@
-// src/hooks/useAuth.ts
-import { useContext } from "react";
-import AuthContext from "../context/AuthContext";
-
-export const useAuth = () => {
-  const context = useContext(AuthContext);
-  if (context === undefined) {
-    throw new Error("useAuth must be used within an AuthProvider");
-  }
-  return context;
-};
Index: ontend/src/index.css
===================================================================
--- frontend/src/index.css	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,55 +1,0 @@
-@import "tailwindcss";
-
-:root {
-    font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
-    line-height: 1.5;
-    font-weight: 400;
-
-    color-scheme: light dark;
-    color: rgba(0, 0, 0, 0.87);
-    background-color: #ececec;
-
-    font-synthesis: none;
-    text-rendering: optimizeLegibility;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-}
-
-@media (prefers-color-scheme: light) {
-    :root {
-        color: #213547;
-        background-color: #ffffff;
-    }
-
-    a:hover {
-        color: #747bff;
-    }
-
-    button {
-        background-color: #f9f9f9;
-    }
-}
-
-.border-b {
-    border-color: rgba(0, 0, 0, 0.12);
-}
-
-.border-l {
-    border-color: rgba(0, 0, 0, 0.12);
-}
-
-.border-r {
-    border-color: rgba(0, 0, 0, 0.12);
-}
-
-.border {
-    border-color: rgba(0, 0, 0, 0.12);
-}
-
-.border-t {
-    border-color: rgba(0, 0, 0, 0.12);
-}
-
-.border-b-2 {
-    border-color: rgba(0, 0, 0, 0.12);
-}
Index: ontend/src/main.tsx
===================================================================
--- frontend/src/main.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,10 +1,0 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
-
-createRoot(document.getElementById('root')!).render(
-  <StrictMode>
-    <App />
-  </StrictMode>,
-)
Index: ontend/src/pages/AnalyticsPage.tsx
===================================================================
--- frontend/src/pages/AnalyticsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,73 +1,0 @@
-// src/pages/AnalyticsPage.tsx
-import { useEffect, useState } from 'react';
-import type { DailyOpsDto } from '../types/api';
-import { analyticsRepository } from '../api/analyticsRepository';
-import { StatCard } from '../components/analytics/StatCard';
-import { TopProductsList } from '../components/analytics/TopProductsList';
-import { ServerPerformanceTable } from '../components/analytics/ServerPerformanceTable';
-import { RevenueByShiftPeriodTable } from '../components/analytics/RevenueByShiftPeriodTable';
-import { ManagerPerformanceTable } from '../components/analytics/ManagerPerformanceTable';
-import { RevenueSplitChart } from '../components/analytics/RevenueSplitChart';
-import { MonthlyRevenueLaborChart } from '../components/analytics/MonthlyRevenueLaborChart';
-import { RevenueByChannelChart } from '../components/analytics/RevenueByChannelChart';
-
-// Simple icons for StatCards
-const RevenueIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v.01" /></svg>;
-const OrdersIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /></svg>;
-const CustomersIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M15 21a6 6 0 00-9-5.197m0 0A5.975 5.975 0 0112 13a5.975 5.975 0 014.5 2.803" /></svg>;
-
-
-export const AnalyticsPage = () => {
-    const [dailyOps, setDailyOps] = useState<DailyOpsDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        analyticsRepository.getDailyOps(30)
-            .then(setDailyOps)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    }, []);
-
-    const totals = dailyOps.reduce((acc, day) => {
-        acc.revenue += day.daily_revenue;
-        acc.orders += day.total_orders;
-        acc.customers += day.unique_customers;
-        return acc;
-    }, { revenue: 0, orders: 0, customers: 0 });
-
-    if (loading) return <div className="p-6">Loading analytics...</div>;
-
-    return (
-        <div className="p-6 bg-gray-50">
-            <h1 className="text-3xl font-bold mb-6">Analytics Dashboard</h1>
-
-            {/* Stat Cards Section */}
-            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
-                <StatCard title="Total Revenue (Last 30 Days)" value={`$${totals.revenue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`} icon={<RevenueIcon />} />
-                <StatCard title="Total Orders (Last 30 Days)" value={totals.orders.toLocaleString()} icon={<OrdersIcon />} />
-                <StatCard title="Unique Customers (Last 30 Days)" value={totals.customers.toLocaleString()} icon={<CustomersIcon />} />
-            </div>
-            <div className="mb-8">
-                <RevenueByChannelChart />
-            </div>
-
-            {/* Charts Section */}
-            <div className="grid grid-cols-1 lg:grid-cols-5 gap-6 mb-8">
-                <div className="lg:col-span-3">
-                    <MonthlyRevenueLaborChart />
-                </div>
-                <div className="lg:col-span-2">
-                    <RevenueSplitChart />
-                </div>
-            </div>
-
-            {/* Tables Section */}
-            <div className="space-y-8">
-                <TopProductsList />
-                <ServerPerformanceTable />
-                <ManagerPerformanceTable />
-                <RevenueByShiftPeriodTable />
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/AssignmentsPage.tsx
===================================================================
--- frontend/src/pages/AssignmentsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,58 +1,0 @@
-// src/pages/AssignmentsPage.tsx
-import { useEffect, useState } from 'react';
-import type { AssignmentDto } from '../types/api';
-import { assignmentRepository } from '../api/assignmentRepository';
-import { Modal } from '../components/Modal';
-import { CreateAssignmentForm } from '../components/forms/CreateAssignmentForm';
-
-export const AssignmentsPage = () => {
-    const [assignments, setAssignments] = useState<AssignmentDto[]>([]);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchAssignments = () => {
-        assignmentRepository.getAllAssignments()
-            .then(setAssignments)
-            .catch(console.error);
-    };
-
-    useEffect(() => {
-        fetchAssignments();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchAssignments();
-    };
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Employee Assignments</h1>
-                <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Create Assignment
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Assignment">
-                <CreateAssignmentForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg p-4">
-                <h2 className="text-xl font-semibold mb-2">Current Assignments</h2>
-                <ul>
-                    {assignments.map(a => (
-                        <li key={a.id} className="border-b py-2">
-                            <span className="font-semibold">{a.employee.email}</span> is assigned to shift on{' '}
-                            <span className="font-semibold">{new Date(a.shift.date).toLocaleDateString()}</span> from{' '}
-                            <span className="font-semibold">{new Date(a.shift.start).toLocaleTimeString()}</span> to{' '}
-                            <span className="font-semibold">{new Date(a.shift.end).toLocaleTimeString()}</span>
-                        </li>
-                    ))}
-                </ul>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/CategoriesPage.tsx
===================================================================
--- frontend/src/pages/CategoriesPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,90 +1,0 @@
-// src/pages/CategoriesPage.tsx
-import { useEffect, useState } from 'react';
-import type { CategoryDto } from '../types/api';
-import { categoryRepository } from '../api/categoryRepository';
-import { Modal } from '../components/Modal';
-import { CreateCategoryForm } from '../components/forms/CreateCategoryForm';
-
-export const CategoriesPage = () => {
-    const [categories, setCategories] = useState<CategoryDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchCategories = () => {
-        setLoading(true);
-        categoryRepository.getAllCategories()
-            .then(setCategories)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchCategories();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchCategories();
-    };
-
-    const handleDelete = async (categoryId: number) => {
-        if (window.confirm('Are you sure you want to delete this category? This may affect existing products.')) {
-            try {
-                await categoryRepository.deleteCategory(categoryId);
-                alert('Category deleted successfully!');
-                fetchCategories();
-            } catch (error) {
-                console.error('Failed to delete category:', error);
-                alert('Failed to delete category.');
-            }
-        }
-    };
-
-    if (loading) return <div>Loading categories...</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Categories</h1>
-                <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Add Category
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Category">
-                <CreateCategoryForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg overflow-hidden">
-                <table className="min-w-full leading-normal">
-                    <thead>
-                        <tr>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Name</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Status</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100"></th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {categories.map(cat => (
-                            <tr key={cat.id}>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm font-semibold">{cat.name}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
-                                    {cat.is_available ?
-                                        <span className="text-green-600">Available</span> :
-                                        <span className="text-red-600">Unavailable</span>
-                                    }
-                                </td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm text-right">
-                                    <button onClick={() => handleDelete(cat.id)} className="text-red-600 hover:text-red-900">Delete</button>
-                                </td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/DashboardPage.tsx
===================================================================
--- frontend/src/pages/DashboardPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,45 +1,0 @@
-// src/pages/DashboardPage.tsx
-import { useAuth } from '../hooks/useAuth';
-import { ROLES } from '../utils/roles';
-import { CurrentShiftCard } from '../components/employee/CurrentShiftCard';
-
-// This is the Manager's dashboard view
-const ManagerDashboard = () => (
-    <>
-        <h1 className="text-3xl font-bold">Manager Dashboard</h1>
-        <p className="mt-2">Welcome back! Here's a summary of today's operations.</p>
-        <div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-4">
-            <div className="bg-white p-6 rounded-lg shadow-md">
-                <h2 className="text-xl font-semibold">Open Orders</h2>
-                <p className="mt-2 text-gray-600">View and manage all incoming and in-progress orders.</p>
-            </div>
-            <div className="bg-white p-6 rounded-lg shadow-md">
-                <h2 className="text-xl font-semibold">Today's Reservations</h2>
-                <p className="mt-2 text-gray-600">See all scheduled reservations for today.</p>
-            </div>
-        </div>
-    </>
-);
-
-// This is the Employee's dashboard view
-const EmployeeDashboard = () => (
-    <>
-        <h1 className="text-3xl font-bold mb-6">Dashboard</h1>
-        <CurrentShiftCard />
-    </>
-);
-
-const DashboardPage = () => {
-    const { user } = useAuth();
-
-    // Determine which dashboard to show based on user role
-    const isManager = user?.user_type === ROLES.MANAGER;
-
-    return (
-        <div className="p-6">
-            {isManager ? <EmployeeDashboard /> : <EmployeeDashboard />}
-        </div>
-    );
-};
-
-export default DashboardPage;
Index: ontend/src/pages/EmployeesPage.tsx
===================================================================
--- frontend/src/pages/EmployeesPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,72 +1,0 @@
-// src/pages/EmployeesPage.tsx
-import { useEffect, useState } from 'react';
-import type { EmployeeDto } from '../types/api';
-import { employeeRepository } from '../api/employeeRepository';
-import { Modal } from '../components/Modal';
-import { CreateEmployeeForm } from '../components/forms/CreateEmployeeForm';
-
-export const EmployeesPage = () => {
-    const [employees, setEmployees] = useState<EmployeeDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchEmployees = () => {
-        setLoading(true);
-        employeeRepository.getAllEmployees()
-            .then(setEmployees)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchEmployees();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchEmployees();
-    };
-
-    if (loading) return <div>Loading employees...</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Employees</h1>
-                <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Add Employee
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Employee">
-                <CreateEmployeeForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg overflow-hidden">
-                <table className="min-w-full leading-normal">
-                    <thead>
-                        <tr>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Email</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Role</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Phone Number</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Gross/Net Salary</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {employees.map(emp => (
-                            <tr key={emp.id}>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{emp.email}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{emp.user_type}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{emp.phone_number}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">${emp.gross_salary} / ${emp.net_salary}</td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/LoginPage.tsx
===================================================================
--- frontend/src/pages/LoginPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,79 +1,0 @@
-// src/pages/LoginPage.tsx
-import React, { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { useAuth } from '../hooks/useAuth';
-import { UserType } from '../types/api'; // Import UserType enum
-
-export const LoginPage = () => {
-    const [username, setUsername] = useState('');
-    const [password, setPassword] = useState('');
-    const [error, setError] = useState('');
-    const { login } = useAuth();
-    const navigate = useNavigate();
-
-    const handleSubmit = async (e: React.FormEvent) => {
-        e.preventDefault();
-        setError('');
-        try {
-            const user = await login({ username, password }); // Capture the returned user object
-
-            // Check the user's role and navigate
-            if ([UserType.MANAGER, UserType.FRONT_STAFF, UserType.BACK_STAFF].includes(user.user_type)) {
-                navigate('/admin'); // Navigate to the admin dashboard
-            } else {
-                navigate('/'); // Navigate to the public menu page for customers
-            }
-
-        } catch (err) {
-            setError('Failed to log in. Please check your credentials.');
-            console.error(err);
-        }
-    };
-
-    return (
-        // ... JSX for the login form remains the same ...
-        <div className="min-h-screen flex items-center justify-center bg-gray-100">
-            <div className="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
-                <h2 className="text-2xl font-bold mb-6 text-center">Login</h2>
-                <form onSubmit={handleSubmit}>
-                    {/* Form fields */}
-                    <div className="mb-4">
-                        <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="email">
-                            Email
-                        </label>
-                        <input
-                            id="email"
-                            type="email"
-                            value={username}
-                            onChange={(e) => setUsername(e.target.value)}
-                            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
-                            required
-                        />
-                    </div>
-                    <div className="mb-6">
-                        <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="password">
-                            Password
-                        </label>
-                        <input
-                            id="password"
-                            type="password"
-                            value={password}
-                            onChange={(e) => setPassword(e.target.value)}
-                            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
-                            required
-                        />
-                    </div>
-                    {error && <p className="text-red-500 text-xs italic mb-4">{error}</p>}
-                    <div className="flex items-center justify-between">
-                        <button
-                            type="submit"
-                            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full"
-                        >
-                            Sign In
-                        </button>
-                    </div>
-                </form>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/OrderDetailsPage.tsx
===================================================================
--- frontend/src/pages/OrderDetailsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,120 +1,0 @@
-// src/pages/OrderDetailsPage.tsx
-import { useCallback, useEffect, useState } from 'react';
-import { useParams, Link } from 'react-router-dom';
-import type { OrderDto } from '../types/api';
-import { orderRepository } from '../api/orderRepository';
-import { AddItemModal } from '../components/AddItemModal';
-import { UpdateOrderStatusActions } from '../components/order/UpdateOrderStatusActions';
-import { PaymentModal } from '../components/modals/PaymentModal';
-
-export const OrderDetailsPage = () => {
-    const { orderId } = useParams<{ orderId: string }>();
-    const [order, setOrder] = useState<OrderDto | null>(null);
-    const [loading, setLoading] = useState(true);
-    const [isAddItemModalOpen, setIsAddItemModalOpen] = useState(false);
-    const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // New state for payment modal
-
-    const fetchOrderDetails = useCallback(() => {
-        if (orderId) {
-            setLoading(true);
-            orderRepository.getOrderById(parseInt(orderId, 10))
-                .then(setOrder)
-                .catch(console.error)
-                .finally(() => setLoading(false));
-        }
-    }, [orderId]);
-
-    useEffect(() => {
-        fetchOrderDetails();
-    }, [orderId, fetchOrderDetails]);
-
-    const handleSuccess = () => {
-        setIsAddItemModalOpen(false);
-        setIsPaymentModalOpen(false); // Close payment modal on success too
-        fetchOrderDetails(); // Generic success handler for all updates
-    };
-
-    if (loading) return <div>Loading order details...</div>;
-    if (!order) return <div>Order not found.</div>;
-
-    const totalPrice = order.order_items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
-    const isPayable = order.status !== 'COMPLETED' && order.status !== 'CANCELED' && totalPrice > 0 && order.status !== 'PAID';
-
-    const getStatusColor = (status: string) => {
-        switch (status) {
-            case 'COMPLETED': return 'bg-green-100 text-green-800';
-            case 'CANCELED': return 'bg-red-100 text-red-800';
-            case 'CONFIRMED': return 'bg-yellow-100 text-yellow-800';
-            case 'PAID': return 'bg-purple-100 text-purple-800';
-            default: return 'bg-blue-100 text-blue-800';
-        }
-    }
-
-    return (
-        <div className="p-6">
-            <Link to="/admin/orders" className="text-blue-600 hover:underline mb-4 block">&larr; Back to All Orders</Link>
-
-            {/* Modals */}
-            {orderId && <AddItemModal isOpen={isAddItemModalOpen} onClose={() => setIsAddItemModalOpen(false)} orderId={parseInt(orderId, 10)} onSuccess={handleSuccess} />}
-            {order && <PaymentModal isOpen={isPaymentModalOpen} onClose={() => setIsPaymentModalOpen(false)} order={order} onSuccess={handleSuccess} />}
-
-            <div className="flex justify-between items-start mb-6">
-                <div>
-                    <h1 className="text-3xl font-bold">Order #{order.id}</h1>
-                    <p className="text-gray-500">Placed on: {new Date(order.timestamp).toLocaleString()}</p>
-                </div>
-                <div className="flex gap-4">
-                    <button onClick={() => setIsAddItemModalOpen(true)} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
-                        + Add Items
-                    </button>
-                    {isPayable && (
-                        <button onClick={() => setIsPaymentModalOpen(true)} className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
-                            Pay
-                        </button>
-                    )}
-                </div>
-            </div>
-
-            <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
-                {/* Order Items */}
-                <div className="md:col-span-2 bg-white p-6 rounded-lg shadow-md">
-                    <h2 className="text-xl font-semibold mb-4 border-b pb-2">Items</h2>
-                    <div className="space-y-3">
-                        {order.order_items.map(item => (
-                            <div key={item.id} className="flex justify-between items-center">
-                                <div>
-                                    <p className="font-semibold">{item.product_name} <span className="text-gray-500 font-normal">x {item.quantity}</span></p>
-                                    <p className="text-sm text-gray-600">@ ${item.price.toFixed(2)} each</p>
-                                </div>
-                                <p className="font-bold">${(item.price * item.quantity).toFixed(2)}</p>
-                            </div>
-                        ))}
-                    </div>
-                    <div className="mt-6 pt-4 border-t flex justify-end">
-                        <p className="text-lg font-bold">Total: ${totalPrice.toFixed(2)}</p>
-                    </div>
-                </div>
-
-                {/* Order Details */}
-                <div className="bg-white p-6 rounded-lg shadow-md">
-                    <h2 className="text-xl font-semibold mb-4 border-b pb-2">Details</h2>
-                    <div className="space-y-3">
-                        <p><strong>Status:</strong> <span className={`px-2 py-1 rounded-full text-sm font-semibold ${getStatusColor(order.status)}`}>{order.status.replace('_', ' ')}</span></p>
-                        <p><strong>Type:</strong> {order.type}</p>
-                        {order.type === 'TAB' && <p><strong>Table:</strong> {order.table_number}</p>}
-                        {order.front_staff_name && <p><strong>Staff:</strong> {order.front_staff_name}</p>}
-                        {order.type === 'ONLINE' && (
-                            <>
-                                <p><strong>Customer:</strong> {order.customer_name}</p>
-                                <p><strong>Address:</strong> {order.delivery_address}</p>
-                            </>
-                        )}
-                    </div>
-                </div>
-
-                <UpdateOrderStatusActions order={order} onSuccess={handleSuccess} />
-
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/OrdersPage.tsx
===================================================================
--- frontend/src/pages/OrdersPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,97 +1,0 @@
-// src/pages/OrdersPage.tsx
-import { useEffect, useState } from 'react';
-import type { OrderDto } from '../types/api';
-import { orderRepository } from '../api/orderRepository';
-import { Modal } from '../components/Modal';
-import { CreateTabOrderForm } from '../components/forms/CreateTabOrderForm';
-import { Link } from 'react-router-dom';
-import { useAuth } from '../hooks/useAuth';
-
-export const OrdersPage = () => {
-    const [openOrders, setOpenOrders] = useState<OrderDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [error, setError] = useState('');
-    const [isModalOpen, setIsModalOpen] = useState(false);
-    const { user } = useAuth();
-
-    const fetchOrders = async () => {
-        try {
-            setLoading(true);
-            const orders = await orderRepository.getOpenOrders();
-            setOpenOrders(orders);
-        } catch (err) {
-            setError('Failed to fetch open orders.');
-            console.error(err);
-        } finally {
-            setLoading(false);
-        }
-    };
-
-    useEffect(() => {
-        fetchOrders();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchOrders(); // Refresh the list after creating a new order
-    };
-
-    if (loading) return <div>Loading orders...</div>;
-    if (error) return <div className="text-red-500">{error}</div>;
-    if (!user) return <div className="text-red-500">User not authenticated.</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Open Orders</h1>
-                {user.user_type === "FRONT_STAFF" && <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Create Tab
-                </button>}
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Tab">
-                <CreateTabOrderForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg overflow-hidden">
-                <table className="min-w-full leading-normal">
-                    <thead>
-                        <tr>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Order ID</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Type / Table</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Status</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Timestamp</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100"></th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {openOrders.map(order => (
-                            <tr key={order.id}>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{order.id}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
-                                    {order.type === 'TAB' ? `Tab - Table ${order.table_number}` : 'Online'}
-                                </td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
-                                    <span className="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight">
-                                        <span aria-hidden className="absolute inset-0 bg-green-200 opacity-50 rounded-full"></span>
-                                        <span className="relative">{order.status}</span>
-                                    </span>
-                                </td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{new Date(order.timestamp).toLocaleString()}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm text-right">
-                                    {/* Update this button to a Link */}
-                                    <Link to={`/admin/orders/${order.id}`} className="text-indigo-600 hover:text-indigo-900 font-semibold">
-                                        View Details
-                                    </Link>
-                                </td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/ProductsPage.tsx
===================================================================
--- frontend/src/pages/ProductsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,85 +1,0 @@
-// src/pages/ProductsPage.tsx
-import { useEffect, useState } from 'react';
-import type { ProductDto } from '../types/api';
-import { productRepository } from '../api/productRepository';
-import { Modal } from '../components/Modal';
-import { CreateProductForm } from '../components/forms/CreateProductForm';
-
-export const ProductsPage = () => {
-    const [products, setProducts] = useState<ProductDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchProducts = () => {
-        setLoading(true);
-        productRepository.getAllProducts()
-            .then(setProducts)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchProducts();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchProducts();
-    };
-
-    const handleDelete = async (productId: number) => {
-        if (window.confirm('Are you sure you want to delete this product?')) {
-            try {
-                await productRepository.deleteProduct(productId);
-                fetchProducts();
-            } catch (error) {
-                alert('Failed to delete product.');
-            }
-        }
-    };
-
-    if (loading) return <div>Loading products...</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Products</h1>
-                <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Add Product
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Product">
-                <CreateProductForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg overflow-hidden">
-                <table className="min-w-full leading-normal">
-                    <thead>
-                        <tr>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Product Name</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Category</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Price</th>
-                            <th className="px-5 py-3 border-b-2 border-gray-200 bg-gray-100"></th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {products.map(prod => (
-                            <tr key={prod.id}>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{prod.name}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">{prod.category.name}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">${prod.price.toFixed(2)}</td>
-                                <td className="px-5 py-5 border-b border-gray-200 bg-white text-sm text-right">
-                                    <button onClick={() => handleDelete(prod.id)} className="text-red-600 hover:text-red-900">Delete</button>
-                                </td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/ReservationsPage.tsx
===================================================================
--- frontend/src/pages/ReservationsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,109 +1,0 @@
-// src/pages/ReservationsPage.tsx
-import { useEffect, useState } from 'react';
-import type { ReservationDto } from '../types/api';
-import { reservationRepository } from '../api/reservationRepository';
-import { Modal } from '../components/Modal';
-import { AcceptReservationForm } from '../components/forms/AcceptReservationForm';
-import { CreateReservationForm } from '../components/forms/CreateReservationForm'; // Import the new form
-import { useAuth } from '../hooks/useAuth';
-import ReservationCard from '../components/reservations/ReservationCard';
-
-export const ReservationsPage = () => {
-    const { user } = useAuth();
-    const [reservations, setReservations] = useState<ReservationDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [selectedReservation, setSelectedReservation] = useState<ReservationDto | null>(null);
-    const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); // State for the creation modal
-
-    const fetchReservations = () => {
-        setLoading(true);
-        reservationRepository.getTodayReservations()
-            .then(data => setReservations(data))
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchReservations();
-    }, []);
-
-    const handleOpenAcceptModal = (reservation: ReservationDto) => {
-        setSelectedReservation(reservation);
-    };
-
-    const handleCloseAcceptModal = () => {
-        setSelectedReservation(null);
-    };
-
-    const handleDeleteReservation = async (reservationId: number) => {
-        if (window.confirm('Are you sure you want to decline this reservation?')) {
-            try {
-                await reservationRepository.deleteReservation(reservationId);
-                fetchReservations();
-            } catch (error) {
-                alert('Failed to decline reservation.');
-            }
-        }
-    };
-
-    const handleFormSuccess = () => {
-        // This function can now be used by both forms
-        handleCloseAcceptModal();
-        setIsCreateModalOpen(false);
-        fetchReservations(); // Refresh data
-    };
-
-    if (loading) return <div>Loading reservations...</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">All Reservations</h1>
-                <button
-                    onClick={() => setIsCreateModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Create Reservation
-                </button>
-            </div>
-
-            {/* Modal for creating a reservation */}
-            <Modal
-                isOpen={isCreateModalOpen}
-                onClose={() => setIsCreateModalOpen(false)}
-                title="Create New Reservation"
-            >
-                <CreateReservationForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            {/* Modal for accepting a reservation */}
-            {selectedReservation && (
-                <Modal
-                    isOpen={!!selectedReservation}
-                    onClose={handleCloseAcceptModal}
-                    title={`Accept Reservation for ${selectedReservation.email}`}
-                >
-                    <AcceptReservationForm
-                        reservationId={selectedReservation.id}
-                        onSuccess={handleFormSuccess}
-                    />
-                </Modal>
-            )}
-
-            <div className="min-h-screen p-4 sm:p-6 lg:p-8">
-                <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
-                    {reservations.map(res => (
-                        <ReservationCard
-                            key={res.id}
-                            reservation={res}
-                            user={user}
-                            onAccept={handleOpenAcceptModal}
-                            onDecline={() => handleDeleteReservation(res.id)}
-                        />
-                    ))}
-                </div>
-            </div>
-
-        </div>
-    );
-};
Index: ontend/src/pages/ShiftsPage.tsx
===================================================================
--- frontend/src/pages/ShiftsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,62 +1,0 @@
-// src/pages/ShiftsPage.tsx
-import { useEffect, useState } from 'react';
-import type { ShiftDto } from '../types/api';
-import { shiftRepository } from '../api/shiftRepository';
-import { Modal } from '../components/Modal';
-import { CreateShiftForm } from '../components/forms/CreateShiftForm';
-
-export const ShiftsPage = () => {
-    const [shifts, setShifts] = useState<ShiftDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchShifts = () => {
-        setLoading(true);
-        shiftRepository.getAllShifts()
-            .then(setShifts)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchShifts();
-    }, []);
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchShifts();
-    };
-
-    if (loading) return <div>Loading shifts...</div>;
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">Shifts</h1>
-                <button
-                    onClick={() => setIsModalOpen(true)}
-                    className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
-                >
-                    + Create Shift
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Create New Shift">
-                <CreateShiftForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            <div className="bg-white shadow-md rounded-lg p-4">
-                <h2 className="text-xl font-semibold mb-2">Scheduled Shifts</h2>
-                <ul>
-                    {shifts.map(shift => (
-                        <li key={shift.id} className="border-b py-2">
-                            Shift on <span className="font-semibold">{new Date(shift.date).toLocaleDateString()}</span> from{' '}
-                            <span className="font-semibold">{new Date(shift.start).toLocaleTimeString()}</span> to{' '}
-                            <span className="font-semibold">{new Date(shift.end).toLocaleTimeString()}</span>
-                        </li>
-                    ))}
-                </ul>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/pages/public/MenuPage.tsx
===================================================================
--- frontend/src/pages/public/MenuPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,129 +1,0 @@
-// src/pages/public/MenuPage.tsx
-import { useEffect, useState } from 'react';
-import type { CategoryDto, ProductDto, CreateOrderDto, CreateOrderItemDto } from '../../types/api';
-import { categoryRepository } from '../../api/categoryRepository';
-import { productRepository } from '../../api/productRepository';
-import { orderRepository } from '../../api/orderRepository';
-import { CartSidebar } from '../../components/public/CartSidebar';
-import { Modal } from '../../components/Modal';
-import { useAuth } from '../../hooks/useAuth';
-import { useNavigate } from 'react-router-dom';
-import { CheckoutForm } from '../../components/public/CheckoutForm';
-
-interface CartItem extends ProductDto {
-    quantity: number;
-}
-
-export const MenuPage = () => {
-    const { isAuthenticated } = useAuth();
-    const navigate = useNavigate();
-    const [categories, setCategories] = useState<CategoryDto[]>([]);
-    const [products, setProducts] = useState<ProductDto[]>([]);
-    const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(null);
-    const [cart, setCart] = useState<Record<number, CartItem>>({});
-    const [isCheckoutModalOpen, setIsCheckoutModalOpen] = useState(false);
-    const [isSubmitting, setIsSubmitting] = useState(false);
-
-    useEffect(() => {
-        Promise.all([
-            categoryRepository.getAllCategories(),
-            productRepository.getAllProducts(),
-        ]).then(([catData, prodData]) => {
-            const availableCats = catData.filter(c => c.is_available);
-            setCategories(availableCats);
-            setProducts(prodData);
-            if (availableCats.length > 0) {
-                setSelectedCategoryId(availableCats[0].id);
-            }
-        }).catch(console.error);
-    }, []);
-
-    const updateCart = (product: ProductDto, change: 1 | -1) => {
-        setCart(prevCart => {
-            const existingItem = prevCart[product.id];
-            const newQuantity = (existingItem?.quantity || 0) + change;
-            if (newQuantity <= 0) {
-                const { [product.id]: _, ...rest } = prevCart;
-                return rest;
-            }
-            return { ...prevCart, [product.id]: { ...product, quantity: newQuantity } };
-        });
-    };
-
-    const handleCheckout = () => {
-        if (!isAuthenticated) {
-            alert("Please log in or register to place an order.");
-            navigate('/login');
-            return;
-        }
-        setIsCheckoutModalOpen(true);
-    };
-
-    const handleConfirmOrder = async (data: { delivery_address: string }) => {
-        setIsSubmitting(true);
-        const orderItems: CreateOrderItemDto[] = Object.values(cart).map(item => ({
-            product_id: item.id,
-            quantity: item.quantity,
-            price: item.price,
-            is_processed: false,
-        }));
-
-        const orderData: CreateOrderDto = {
-            order_items: orderItems,
-            status: "PENDING",
-            type: "ONLINE",
-            delivery_address: data.delivery_address,
-        };
-
-        try {
-            await orderRepository.createOnlineOrder(orderData);
-            alert("Order placed successfully!");
-            setCart({});
-            setIsCheckoutModalOpen(false);
-        } catch (error) {
-            alert("Failed to place order.");
-
-            console.error(error);
-        } finally {
-            setIsSubmitting(false);
-        }
-    };
-
-    const filteredProducts = products.filter(p => p.category.id === selectedCategoryId);
-
-    return (
-        <div className="flex flex-col md:flex-row p-4 gap-4 bg-gray-50 h-[calc(100vh-68px)]">
-            {/* Menu */}
-            <div className="flex-grow">
-                <div className="flex space-x-2 overflow-x-auto pb-2">
-                    {categories.map(cat => (
-                        <button key={cat.id} onClick={() => setSelectedCategoryId(cat.id)}
-                            className={`px-4 py-2 rounded-full font-semibold whitespace-nowrap ${selectedCategoryId === cat.id ? 'bg-blue-500 text-white' : 'bg-white'}`}>
-                            {cat.name}
-                        </button>
-                    ))}
-                </div>
-                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-4">
-                    {filteredProducts.map(prod => (
-                        <div key={prod.id} className="bg-white p-4 rounded-lg shadow">
-                            <h4 className="font-bold">{prod.name}</h4>
-                            <p className="text-sm text-gray-500">{prod.description}</p>
-                            <div className="flex justify-between items-center mt-2">
-                                <span className="font-semibold">${prod.price.toFixed(2)}</span>
-                                <button onClick={() => updateCart(prod, 1)} className="bg-blue-100 text-blue-800 font-bold py-1 px-3 rounded">Add</button>
-                            </div>
-                        </div>
-                    ))}
-                </div>
-            </div>
-            {/* Cart */}
-            <div className="w-full md:w-80 lg:w-96 flex-shrink-0">
-                <CartSidebar cart={cart} onUpdateQuantity={updateCart} onCheckout={handleCheckout} />
-            </div>
-
-            <Modal isOpen={isCheckoutModalOpen} onClose={() => setIsCheckoutModalOpen(false)} title="Complete Your Order">
-                <CheckoutForm onSubmit={handleConfirmOrder} isSubmitting={isSubmitting} />
-            </Modal>
-        </div>
-    );
-};
Index: ontend/src/pages/public/MyOrdersPage.tsx
===================================================================
--- frontend/src/pages/public/MyOrdersPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,67 +1,0 @@
-// src/pages/public/MyOrdersPage.tsx
-import { useEffect, useState } from 'react';
-import type { OrderDto } from '../../types/api';
-import { orderRepository } from '../../api/orderRepository';
-import { useAuth } from '../../hooks/useAuth';
-
-const getStatusColor = (status: string) => {
-    switch (status) {
-        case 'COMPLETED': return 'bg-green-100 text-green-800';
-        case 'CANCELED': return 'bg-red-100 text-red-800';
-        case 'IN_PROGRESS': return 'bg-yellow-100 text-yellow-800';
-        default: return 'bg-blue-100 text-blue-800';
-    }
-};
-
-export const MyOrdersPage = () => {
-    const { user } = useAuth();
-    const [orders, setOrders] = useState<OrderDto[]>([]);
-    const [loading, setLoading] = useState(true);
-
-    useEffect(() => {
-        if (user) {
-            setLoading(true);
-            orderRepository.getOnlineOrdersByCustomer(user.id)
-                .then(setOrders)
-                .catch(console.error)
-                .finally(() => setLoading(false));
-        }
-    }, [user]);
-
-    if (loading) return <p className="p-6">Loading your orders...</p>;
-
-    return (
-        <div className="p-6 bg-gray-50 min-h-screen">
-            <h1 className="text-3xl font-bold mb-4">My Orders</h1>
-
-            {orders.length === 0 ? (
-                <p>You haven't placed any orders yet. Visit our menu to get started!</p>
-            ) : (
-                <div className="space-y-4">
-                    {orders.map(order => {
-                        const totalPrice = order.order_items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
-                        return (
-                            <div key={order.id} className="bg-white p-4 rounded-lg shadow-md">
-                                <div className="flex justify-between items-start">
-                                    <div>
-                                        <p className="font-bold text-lg">Order #{order.id}</p>
-                                        <p className="text-sm text-gray-500">
-                                            Placed on: {new Date(order.timestamp).toLocaleDateString()}
-                                        </p>
-                                    </div>
-                                    <span className={`px-2 py-1 rounded-full text-xs font-semibold ${getStatusColor(order.status)}`}>
-                                        {order.status.replace('_', ' ')}
-                                    </span>
-                                </div>
-                                <div className="mt-4 border-t pt-2">
-                                    <p><strong>Address:</strong> {order.delivery_address}</p>
-                                    <p><strong>Total:</strong> ${totalPrice.toFixed(2)}</p>
-                                </div>
-                            </div>
-                        );
-                    })}
-                </div>
-            )}
-        </div>
-    );
-};
Index: ontend/src/pages/public/MyReservationsPage.tsx
===================================================================
--- frontend/src/pages/public/MyReservationsPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,75 +1,0 @@
-// src/pages/public/MyReservationsPage.tsx
-import { useEffect, useState } from 'react';
-import type { ReservationDto } from '../../types/api';
-import { reservationRepository } from '../../api/reservationRepository';
-import { Modal } from '../../components/Modal';
-import { CreateReservationForm } from '../../components/forms/CreateReservationForm';
-
-export const MyReservationsPage = () => {
-    const [reservations, setReservations] = useState<ReservationDto[]>([]);
-    const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
-
-    const fetchReservations = () => {
-        setLoading(true);
-        reservationRepository.getMyReservations()
-            .then(setReservations)
-            .catch(console.error)
-            .finally(() => setLoading(false));
-    };
-
-    useEffect(() => {
-        fetchReservations();
-    }, []);
-
-    const handleCancel = async (id: number) => {
-        if (window.confirm("Are you sure you want to cancel this reservation?")) {
-            try {
-                await reservationRepository.deleteReservation(id);
-                alert("Reservation canceled.");
-                fetchReservations();
-            } catch (error) {
-                alert("Failed to cancel reservation.");
-            }
-        }
-    };
-
-    const handleFormSuccess = () => {
-        setIsModalOpen(false);
-        fetchReservations();
-    };
-
-    return (
-        <div className="p-6">
-            <div className="flex justify-between items-center mb-4">
-                <h1 className="text-3xl font-bold">My Reservations</h1>
-                <button onClick={() => setIsModalOpen(true)} className="bg-green-500 text-white font-bold py-2 px-4 rounded">
-                    + Make a Reservation
-                </button>
-            </div>
-
-            <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} title="Make a New Reservation">
-                <CreateReservationForm onSuccess={handleFormSuccess} />
-            </Modal>
-
-            {loading ? <p>Loading...</p> : reservations.length === 0 ? (
-                <p>You have no upcoming reservations.</p>
-            ) : (
-                <div className="space-y-4">
-                    {reservations.map(res => (
-                        <div key={res.id} className="bg-white p-4 rounded-lg shadow-md flex justify-between items-center">
-                            <div>
-                                <p><strong>Date:</strong> {new Date(res.datetime).toLocaleDateString()}</p>
-                                <p><strong>Time:</strong> {new Date(res.datetime).toLocaleTimeString()}</p>
-                                <p><strong>Guests:</strong> {res.number_of_people}</p>
-                            </div>
-                            <button onClick={() => handleCancel(res.id)} className="bg-red-500 text-white font-bold py-1 px-3 rounded">
-                                Cancel
-                            </button>
-                        </div>
-                    ))}
-                </div>
-            )}
-        </div>
-    );
-};
Index: ontend/src/pages/public/RegisterPage.tsx
===================================================================
--- frontend/src/pages/public/RegisterPage.tsx	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,64 +1,0 @@
-// src/pages/public/RegisterPage.tsx
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { useNavigate } from 'react-router-dom';
-import { useAuth } from '../../hooks/useAuth';
-import { authRepository } from '../../api/authRepository';
-
-const registerSchema = z.object({
-    first_name: z.string().min(1, "First name is required"),
-    last_name: z.string().min(1, "Last name is required"),
-    email: z.string().email(),
-    password: z.string().min(6, "Password must be at least 6 characters"),
-    password_confirmation: z.string()
-}).refine(data => data.password === data.password_confirmation, {
-    message: "Passwords do not match",
-    path: ["password_confirmation"],
-});
-
-type RegisterFormData = z.infer<typeof registerSchema>;
-
-export const RegisterPage = () => {
-    const navigate = useNavigate();
-    const { login } = useAuth(); // We'll use this to log the user in after registration
-    const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<RegisterFormData>({
-        resolver: zodResolver(registerSchema),
-    });
-
-    const onSubmit = async (data: RegisterFormData) => {
-        try {
-            await authRepository.register(data);
-            // Automatically log in the user after successful registration
-            await login({ username: data.email, password: data.password });
-            navigate('/');
-        } catch (error) {
-            console.error(error);
-            alert('Registration failed. The email might already be in use.');
-        }
-    };
-
-    return (
-        <div className="min-h-screen flex items-center justify-center bg-gray-50">
-            <div className="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
-                <h2 className="text-2xl font-bold mb-6 text-center">Create an Account</h2>
-                <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-                    {/* Form fields for first_name, last_name, email, password, password_confirmation */}
-                    <input {...register('first_name')} placeholder="First Name" className="w-full p-2 border rounded" />
-                    {errors.first_name && <p className="text-red-500 text-xs">{errors.first_name.message}</p>}
-                    <input {...register('last_name')} placeholder="Last Name" className="w-full p-2 border rounded" />
-                    {errors.last_name && <p className="text-red-500 text-xs">{errors.last_name.message}</p>}
-                    <input {...register('email')} placeholder="Email" className="w-full p-2 border rounded" />
-                    {errors.email && <p className="text-red-500 text-xs">{errors.email.message}</p>}
-                    <input type="password" {...register('password')} placeholder="Password" className="w-full p-2 border rounded" />
-                    {errors.password && <p className="text-red-500 text-xs">{errors.password.message}</p>}
-                    <input type="password" {...register('password_confirmation')} placeholder="Confirm Password" className="w-full p-2 border rounded" />
-                    {errors.password_confirmation && <p className="text-red-500 text-xs">{errors.password_confirmation.message}</p>}
-                    <button type="submit" disabled={isSubmitting} className="w-full bg-blue-500 text-white p-3 rounded">
-                        {isSubmitting ? 'Registering...' : 'Register'}
-                    </button>
-                </form>
-            </div>
-        </div>
-    );
-};
Index: ontend/src/types/api.ts
===================================================================
--- frontend/src/types/api.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,272 +1,0 @@
-// src/types/api.ts
-
-// Enum for user roles, centralizing the role definitions.
-export enum UserType {
-  CUSTOMER = "CUSTOMER",
-  MANAGER = "MANAGER",
-  FRONT_STAFF = "FRONT_STAFF",
-  BACK_STAFF = "BACK_STAFF",
-  USER = "USER",
-  EMPLOYEE = "EMPLOYEE",
-}
-
-// DTOs (Data Transfer Objects)
-
-export interface UserDto {
-  id: number;
-  email: string;
-  street?: string;
-  city?: string;
-  phone_number?: string;
-  user_type: UserType;
-}
-
-export interface AuthDto {
-  token: string;
-  user: UserDto;
-}
-
-export interface AuthRequest {
-  username?: string; // API docs say username, but likely email
-  password?: string;
-}
-
-export interface OrderItemDto {
-  id: number;
-  quantity: number;
-  price: number;
-  is_processed: boolean;
-  timestamp: string;
-  product_id: number;
-  product_name: string;
-}
-
-export interface OrderDto {
-  id: number;
-  timestamp: string;
-  status: string; // e.g., "PENDING", "IN_PROGRESS", "COMPLETED"
-  type: string; // "ONLINE" or "TAB"
-  customer_name?: string;
-  delivery_address?: string;
-  table_number?: number;
-  front_staff_name?: string;
-  order_items: OrderItemDto[];
-}
-
-export interface CreateOrderDto {
-  order_items: CreateOrderItemDto[];
-  status: string;
-  type: string;
-  delivery_address?: string;
-  table_number?: number;
-}
-
-export interface CreateOrderItemDto {
-  product_id: number;
-  quantity: number;
-  price: number;
-  is_processed: boolean;
-}
-
-export interface ReservationDto {
-  id: number;
-  stay_length: number;
-  datetime: string;
-  creation_timestamp: string;
-  number_of_people: number;
-  assigned_table_number?: number;
-  front_staff_name?: string; // Assuming manager email
-  status: "PENDING" | "ACCEPTED" | "CANCELLED" | "COMPLETED";
-  email: string; // Assuming user email
-}
-
-export interface CreateReservationDto {
-  stay_length: number;
-  datetime: string;
-  number_of_people: number;
-}
-
-export interface ShiftDto {
-  id: number;
-  date: string;
-  start: string;
-  end: string;
-}
-
-export interface AssignmentDto {
-  id: number;
-  clock_in_time?: string;
-  clock_out_time?: string;
-  manager: ManagerDto;
-  employee: EmployeeDto;
-  shift: ShiftDto;
-}
-
-export interface CreateAssignmentDto {
-  employee_id: number;
-  shift_id: number;
-}
-
-// src/types/api.ts (add these interfaces)
-
-export interface CreateShiftDto {
-  date: string; // "YYYY-MM-DD"
-  start: string; // "YYYY-MM-DDTHH:mm:ss"
-  end: string; // "YYYY-MM-DDTHH:mm:ss"
-}
-
-export interface CreateEmployeeRequest {
-  email: string;
-  password?: string;
-  street?: string;
-  city?: string;
-  phone_number?: string;
-  net_salary: number;
-  gross_salary: number;
-  employee_type: "MANAGER" | "FRONT_STAFF" | "BACK_STAFF";
-  staff_role_id?: number;
-  tip_percent?: number;
-}
-
-export interface EmployeeDto {
-  id: number;
-  email: string;
-  street: string;
-  city: string;
-  phone_number: string;
-  net_salary: number;
-  gross_salary: number;
-  user_type: UserType;
-}
-
-// src/types/api.ts (add these interfaces)
-
-export interface CategoryDto {
-  id: number;
-  name: string;
-  is_available: boolean;
-}
-
-export interface CreateCategoryDto {
-  name: string;
-  is_available: boolean;
-}
-
-export interface ProductDto {
-  id: number;
-  name: string;
-  price: number;
-  description: string;
-  category: CategoryDto;
-}
-
-export interface CreateProductDto {
-  name: string;
-  price: number;
-  description: string;
-  category_id: number;
-  tax_class: string; // e.g., "STANDARD", "REDUCED"
-  manage_inventory: boolean;
-  quantity?: number;
-  restock_level?: number;
-}
-
-export interface ShiftDto {
-  id: number;
-  date: string; // "YYYY-MM-DD"
-  start: string; // ISO DateTime string "YYYY-MM-DDTHH:mm:ss"
-  end: string; // ISO DateTime string "YYYY-MM-DDTHH:mm:ss"
-}
-
-export interface ManagerDto {
-  id: number;
-  email: string;
-}
-
-// src/types/api.ts (add this interface)
-
-export interface RegisterRequest {
-  email: string;
-  password?: string;
-  password_confirmation?: string;
-  first_name?: string;
-  last_name?: string;
-}
-
-export interface DailyOpsDto {
-  operation_date: string;
-  total_reservations: number;
-  total_orders: number;
-  unique_customers: number;
-  active_employees: number;
-  daily_revenue: number;
-}
-
-export interface TopProductDto {
-  product_name: string;
-  category_name: string;
-  total_quantity_sold: number;
-  total_revenue: number;
-}
-
-export interface ServerPerformanceDto {
-  server_email: string;
-  total_assignments: number;
-  orders_processed: number;
-  total_revenue_generated: number;
-  avg_order_value: number;
-}
-
-// src/types/api.ts (add these interfaces)
-
-export interface RevenueSplitDto {
-  order_type: string;
-  total_revenue: number;
-}
-
-export interface MonthlyRevenueVsLaborDto {
-  period: string; // e.g., "2025-08"
-  total_revenue: number;
-  total_labor_cost: number;
-}
-
-export interface ManagerShiftAboveAvgDto {
-  manager_email: string;
-  shift_date: string;
-  shift_revenue: number;
-  shift_start_time: string;
-  shift_end_time: string;
-  avg_revenue_per_shift: number;
-}
-
-export interface CreatePaymentDto {
-  tip_amount: number;
-  payment_type: string; // "CASH" or "CARD"
-  amount: number;
-  order_id: number;
-}
-
-export interface PaymentsDailyChannelDto {
-  day: string; // LocalDate
-  channel: string;
-  paid_orders_cnt: number;
-  revenue: number;
-  tip_total: number;
-}
-
-export interface ChannelTableDto {
-  channel: string;
-  data: PaymentsDailyChannelDto[];
-  total_paid_orders: number;
-  total_revenue: number;
-  total_tips: number;
-}
-
-export interface AnalyticsByChannelResponse {
-  from: string; // LocalDate
-  to: string; // LocalDate
-  channels: ChannelTableDto[];
-  grand_total_paid_orders: number;
-  grand_total_revenue: number;
-  grand_total_tips: number;
-}
Index: ontend/src/utils/roles.ts
===================================================================
--- frontend/src/utils/roles.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,31 +1,0 @@
-// src/utils/roles.ts
-import { UserType } from "../types/api";
-
-export const ROLES = {
-  MANAGER: UserType.MANAGER,
-  FRONT_STAFF: UserType.FRONT_STAFF,
-  BACK_STAFF: UserType.BACK_STAFF,
-  CUSTOMER: UserType.CUSTOMER,
-  USER: UserType.USER,
-  EMPLOYEE: UserType.EMPLOYEE,
-};
-
-// Define which pages each role can see in the navigation
-export const ROLE_PERMISSIONS: Record<UserType, string[]> = {
-  [UserType.MANAGER]: [
-    "/admin/orders",
-    "/admin/reservations",
-    "/admin/categories",
-    "/admin/products",
-    "/admin/shifts",
-    "/admin/employees",
-    "/admin/assignments",
-    "/admin/analytics",
-  ],
-  [UserType.FRONT_STAFF]: ["/admin/orders", "/admin/reservations"],
-  [UserType.BACK_STAFF]: ["/admin/orders"],
-  // Other roles are not part of the admin panel MVP
-  [UserType.CUSTOMER]: [],
-  [UserType.USER]: [],
-  [UserType.EMPLOYEE]: [],
-};
Index: ontend/src/vite-env.d.ts
===================================================================
--- frontend/src/vite-env.d.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,1 +1,0 @@
-/// <reference types="vite/client" />
Index: ontend/tsconfig.app.json
===================================================================
--- frontend/tsconfig.app.json	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,27 +1,0 @@
-{
-  "compilerOptions": {
-    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
-    "target": "ES2022",
-    "useDefineForClassFields": true,
-    "lib": ["ES2022", "DOM", "DOM.Iterable"],
-    "module": "ESNext",
-    "skipLibCheck": true,
-
-    /* Bundler mode */
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "verbatimModuleSyntax": true,
-    "moduleDetection": "force",
-    "noEmit": true,
-    "jsx": "react-jsx",
-
-    /* Linting */
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "erasableSyntaxOnly": true,
-    "noFallthroughCasesInSwitch": true,
-    "noUncheckedSideEffectImports": true
-  },
-  "include": ["src"]
-}
Index: ontend/tsconfig.json
===================================================================
--- frontend/tsconfig.json	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,7 +1,0 @@
-{
-  "files": [],
-  "references": [
-    { "path": "./tsconfig.app.json" },
-    { "path": "./tsconfig.node.json" }
-  ]
-}
Index: ontend/tsconfig.node.json
===================================================================
--- frontend/tsconfig.node.json	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,25 +1,0 @@
-{
-  "compilerOptions": {
-    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
-    "target": "ES2023",
-    "lib": ["ES2023"],
-    "module": "ESNext",
-    "skipLibCheck": true,
-
-    /* Bundler mode */
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "verbatimModuleSyntax": true,
-    "moduleDetection": "force",
-    "noEmit": true,
-
-    /* Linting */
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "erasableSyntaxOnly": true,
-    "noFallthroughCasesInSwitch": true,
-    "noUncheckedSideEffectImports": true
-  },
-  "include": ["vite.config.ts"]
-}
Index: ontend/vite.config.ts
===================================================================
--- frontend/vite.config.ts	(revision e0c3cd5438ea818d96bfe04bbb97cb4521537c1b)
+++ 	(revision )
@@ -1,8 +1,0 @@
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react";
-import tailwindcss from "@tailwindcss/vite";
-
-// https://vite.dev/config/
-export default defineConfig({
-  plugins: [react(), tailwindcss()],
-});
Index: mvnw
===================================================================
--- mvnw	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ mvnw	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,259 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.2
+#
+# Optional ENV vars
+# -----------------
+#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
+#   MVNW_REPOURL - repo url base for downloading maven distribution
+#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+  native_path() { cygpath --path --windows "$1"; }
+  ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+  if [ -n "${JAVA_HOME-}" ]; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+      JAVACCMD="$JAVA_HOME/jre/sh/javac"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+      JAVACCMD="$JAVA_HOME/bin/javac"
+
+      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+        return 1
+      fi
+    fi
+  else
+    JAVACMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v java
+    )" || :
+    JAVACCMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v javac
+    )" || :
+
+    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+      return 1
+    fi
+  fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+  str="${1:-}" h=0
+  while [ -n "$str" ]; do
+    char="${str%"${str#?}"}"
+    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+    str="${str#?}"
+  done
+  printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+  printf %s\\n "$1" >&2
+  exit 1
+}
+
+trim() {
+  # MWRAPPER-139:
+  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+  #   Needed for removing poorly interpreted newline sequences when running in more
+  #   exotic environments such as mingw bash on Windows.
+  printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+  case "${key-}" in
+  distributionUrl) distributionUrl=$(trim "${value-}") ;;
+  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+  esac
+done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+  *)
+    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+    distributionPlatform=linux-amd64
+    ;;
+  esac
+  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+  ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+  trap clean HUP INT TERM EXIT
+else
+  die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+  distributionUrl="${distributionUrl%.zip}.tar.gz"
+  distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+  verbose "Found wget ... using wget"
+  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+  verbose "Found curl ... using curl"
+  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+  verbose "Falling back to use Java to download"
+  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+  cat >"$javaSource" <<-END
+	public class Downloader extends java.net.Authenticator
+	{
+	  protected java.net.PasswordAuthentication getPasswordAuthentication()
+	  {
+	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+	  }
+	  public static void main( String[] args ) throws Exception
+	  {
+	    setDefault( new Downloader() );
+	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+	  }
+	}
+	END
+  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+  verbose " - Compiling Downloader.java ..."
+  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+  verbose " - Running Downloader.java ..."
+  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+  distributionSha256Result=false
+  if [ "$MVN_CMD" = mvnd.sh ]; then
+    echo "Checksum validation is not supported for maven-mvnd." >&2
+    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+    exit 1
+  elif command -v sha256sum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  elif command -v shasum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  else
+    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+    exit 1
+  fi
+  if [ $distributionSha256Result = false ]; then
+    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+    exit 1
+  fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
+else
+  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
+fi
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"
Index: mvnw.cmd
===================================================================
--- mvnw.cmd	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ mvnw.cmd	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,149 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM   MVNW_REPOURL - repo url base for downloading maven distribution
+@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+  $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+  "maven-mvnd-*" {
+    $USE_MVND = $true
+    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+    $MVN_CMD = "mvnd.cmd"
+    break
+  }
+  default {
+    $USE_MVND = $false
+    $MVN_CMD = $script -replace '^mvnw','mvn'
+    break
+  }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+if ($env:MVNW_REPOURL) {
+  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+  exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+  if ($TMP_DOWNLOAD_DIR.Exists) {
+    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+  }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+  if ($USE_MVND) {
+    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+  }
+  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+  }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+    Write-Error "fail to move MAVEN_HOME"
+  }
+} finally {
+  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
Index: pom.xml
===================================================================
--- pom.xml	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ pom.xml	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>3.5.3</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>finki.db</groupId>
+    <artifactId>Tasty_Tabs</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>Tasty Tabs</name>
+    <description>Tasty Tabs</description>
+    <url/>
+    <licenses>
+        <license/>
+    </licenses>
+    <developers>
+        <developer/>
+    </developers>
+    <scm>
+        <connection/>
+        <developerConnection/>
+        <tag/>
+        <url/>
+    </scm>
+    <properties>
+        <java.version>17</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.flywaydb</groupId>
+            <artifactId>flyway-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.flywaydb</groupId>
+            <artifactId>flyway-database-postgresql</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.springframework.boot</groupId>
+                            <artifactId>spring-boot-configuration-processor</artifactId>
+                        </path>
+                        <path>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
Index: src/main/java/finki/db/tasty_tabs/TastyTabsApplication.java
===================================================================
--- src/main/java/finki/db/tasty_tabs/TastyTabsApplication.java	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ src/main/java/finki/db/tasty_tabs/TastyTabsApplication.java	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,13 @@
+package finki.db.tasty_tabs;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class TastyTabsApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(TastyTabsApplication.class, args);
+    }
+
+}
Index: src/main/resources/application.properties
===================================================================
--- src/main/resources/application.properties	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ src/main/resources/application.properties	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,5 @@
+spring.application.name=Tasty Tabs
+spring.datasource.url=jdbc:postgresql://localhost:5433/your_db
+spring.datasource.username=your_db_user
+spring.datasource.password=your_db_password
+
Index: src/test/java/finki/db/tasty_tabs/TastyTabsApplicationTests.java
===================================================================
--- src/test/java/finki/db/tasty_tabs/TastyTabsApplicationTests.java	(revision 700c4e06cc622248906302100c15abd8d3500209)
+++ src/test/java/finki/db/tasty_tabs/TastyTabsApplicationTests.java	(revision 700c4e06cc622248906302100c15abd8d3500209)
@@ -0,0 +1,13 @@
+package finki.db.tasty_tabs;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class TastyTabsApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}
