Implementiere Marktmanagement-Datenmodell
This commit is contained in:
1 parent
8492db2e39
commit
2607f448ad
4 files changed
+527
-3
No files matched your search
@@ -0,0 +1,215 @@
|
||||
BEGIN;
|
||||
|
||||
-- Market Management base schema.
|
||||
-- Fachliche Ownership: market_management.
|
||||
|
||||
CREATE TABLE market_category (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
code TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_market_category_code ON market_category(code);
|
||||
CREATE UNIQUE INDEX uq_market_category_name ON market_category(name);
|
||||
|
||||
INSERT INTO market_category (code, name)
|
||||
VALUES
|
||||
('herbstmarkt', 'Herbstmärkte'),
|
||||
('weihnachtsmarkt', 'Weihnachtsmärkte'),
|
||||
('fruehlingsmarkt', 'Frühlingsmärkte'),
|
||||
('ostermarkt', 'Ostermärkte'),
|
||||
('kunsthandwerksmarkt', 'Kunsthandwerksmärkte'),
|
||||
('regionalmarkt', 'Regionalmärkte'),
|
||||
('weitere_geeignete_maerkte', 'Weitere geeignete Märkte');
|
||||
|
||||
CREATE TABLE market_municipality_reference (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
bfs_municipality_number INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
canton_code TEXT NOT NULL,
|
||||
data_version DATE NOT NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_market_municipality_reference_bfs_number_version
|
||||
ON market_municipality_reference(bfs_municipality_number, data_version);
|
||||
CREATE INDEX idx_market_municipality_reference_canton
|
||||
ON market_municipality_reference(canton_code, name);
|
||||
|
||||
CREATE TABLE market_definition (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
category_id BIGINT NOT NULL REFERENCES market_category(id) ON DELETE RESTRICT,
|
||||
archived_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_market_definition_name ON market_definition(name);
|
||||
CREATE INDEX idx_market_definition_category ON market_definition(category_id);
|
||||
|
||||
CREATE TABLE market_occurrence (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
market_definition_id BIGINT NOT NULL REFERENCES market_definition(id) ON DELETE RESTRICT,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
place TEXT,
|
||||
address TEXT,
|
||||
municipality_reference_id BIGINT REFERENCES market_municipality_reference(id) ON DELETE RESTRICT,
|
||||
notes TEXT,
|
||||
registration_deadline DATE,
|
||||
request_or_registration_date DATE,
|
||||
confirmation_date DATE,
|
||||
payment_deadline DATE,
|
||||
stand_size TEXT,
|
||||
table_available BOOLEAN,
|
||||
table_rentable BOOLEAN,
|
||||
own_table_required BOOLEAN,
|
||||
shelter_available BOOLEAN,
|
||||
power_available BOOLEAN,
|
||||
water_available BOOLEAN,
|
||||
lighting_available BOOLEAN,
|
||||
other_infrastructure TEXT,
|
||||
own_stand_requirements TEXT,
|
||||
travel_address TEXT,
|
||||
travel_distance_km NUMERIC(10, 2),
|
||||
travel_duration_minutes INTEGER,
|
||||
parking_options TEXT,
|
||||
delivery_access TEXT,
|
||||
direct_unload_possible BOOLEAN,
|
||||
storage_options TEXT,
|
||||
travel_notes TEXT,
|
||||
payment_status TEXT NOT NULL DEFAULT 'unpaid',
|
||||
payment_date DATE,
|
||||
paid_amount NUMERIC(14, 2),
|
||||
payment_method_code TEXT,
|
||||
cancellation_terms TEXT,
|
||||
revenue_share_terms TEXT,
|
||||
other_participation_conditions TEXT,
|
||||
contract_folder_url TEXT,
|
||||
archived_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT chk_market_occurrence_status CHECK (
|
||||
status IN ('open', 'waitlist', 'registered', 'confirmation_pending', 'confirmed', 'cancelled', 'completed')
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_payment_status CHECK (
|
||||
payment_status IN ('paid', 'unpaid')
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_travel_distance CHECK (
|
||||
travel_distance_km IS NULL OR travel_distance_km >= 0
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_travel_duration CHECK (
|
||||
travel_duration_minutes IS NULL OR travel_duration_minutes >= 0
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_paid_amount CHECK (
|
||||
paid_amount IS NULL OR paid_amount >= 0
|
||||
)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_market_occurrence_market ON market_occurrence(market_definition_id);
|
||||
CREATE INDEX idx_market_occurrence_status ON market_occurrence(status);
|
||||
CREATE INDEX idx_market_occurrence_municipality
|
||||
ON market_occurrence(municipality_reference_id);
|
||||
CREATE INDEX idx_market_occurrence_archived_at ON market_occurrence(archived_at);
|
||||
|
||||
CREATE TABLE market_occurrence_organizer (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
occurrence_id BIGINT NOT NULL UNIQUE REFERENCES market_occurrence(id) ON DELETE RESTRICT,
|
||||
organization_contact_id BIGINT NOT NULL,
|
||||
contact_person_id BIGINT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_market_occurrence_organizer_organization
|
||||
ON market_occurrence_organizer(organization_contact_id);
|
||||
CREATE INDEX idx_market_occurrence_organizer_contact_person
|
||||
ON market_occurrence_organizer(contact_person_id);
|
||||
|
||||
CREATE TABLE market_occurrence_day (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
occurrence_id BIGINT NOT NULL REFERENCES market_occurrence(id) ON DELETE RESTRICT,
|
||||
date DATE NOT NULL,
|
||||
stand_start_time TIME,
|
||||
stand_end_time TIME,
|
||||
setup_start_time TIME,
|
||||
setup_end_time TIME,
|
||||
delivery_start_time TIME,
|
||||
delivery_end_time TIME,
|
||||
observations TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT chk_market_occurrence_day_stand_time CHECK (
|
||||
stand_start_time IS NULL OR stand_end_time IS NULL OR stand_end_time >= stand_start_time
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_day_setup_time CHECK (
|
||||
setup_start_time IS NULL OR setup_end_time IS NULL OR setup_end_time >= setup_start_time
|
||||
),
|
||||
CONSTRAINT chk_market_occurrence_day_delivery_time CHECK (
|
||||
delivery_start_time IS NULL OR delivery_end_time IS NULL OR delivery_end_time >= delivery_start_time
|
||||
)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_market_occurrence_day_date ON market_occurrence_day(occurrence_id, date);
|
||||
CREATE INDEX idx_market_occurrence_day_date ON market_occurrence_day(date);
|
||||
|
||||
CREATE TABLE market_occurrence_cost_item (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
occurrence_id BIGINT NOT NULL REFERENCES market_occurrence(id) ON DELETE RESTRICT,
|
||||
cost_type TEXT NOT NULL,
|
||||
description TEXT,
|
||||
gross_amount NUMERIC(14, 2) NOT NULL,
|
||||
tax_status TEXT NOT NULL,
|
||||
tax_rate NUMERIC(5, 2) NOT NULL DEFAULT 0,
|
||||
tax_amount NUMERIC(14, 2) GENERATED ALWAYS AS (
|
||||
CASE
|
||||
WHEN tax_status = 'tax_free' THEN 0
|
||||
ELSE ROUND(gross_amount - gross_amount / (1 + tax_rate / 100), 2)
|
||||
END
|
||||
) STORED,
|
||||
net_amount NUMERIC(14, 2) GENERATED ALWAYS AS (
|
||||
gross_amount - CASE
|
||||
WHEN tax_status = 'tax_free' THEN 0
|
||||
ELSE ROUND(gross_amount - gross_amount / (1 + tax_rate / 100), 2)
|
||||
END
|
||||
) STORED,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT chk_market_occurrence_cost_gross_nonnegative CHECK (gross_amount >= 0),
|
||||
CONSTRAINT chk_market_occurrence_cost_tax_status CHECK (tax_status IN ('tax_free', 'taxable')),
|
||||
CONSTRAINT chk_market_occurrence_cost_tax_rate CHECK (
|
||||
(tax_status = 'tax_free' AND tax_rate = 0)
|
||||
OR (tax_status = 'taxable' AND tax_rate > 0)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_market_occurrence_cost_item_occurrence
|
||||
ON market_occurrence_cost_item(occurrence_id);
|
||||
|
||||
CREATE TABLE market_mcp_idempotency (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_subject TEXT NOT NULL,
|
||||
client_id TEXT NOT NULL,
|
||||
idempotency_key TEXT NOT NULL,
|
||||
tool_name TEXT NOT NULL,
|
||||
request_hash TEXT NOT NULL,
|
||||
result_status TEXT NOT NULL,
|
||||
result_entity_type TEXT,
|
||||
result_entity_id TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
CONSTRAINT chk_market_mcp_idempotency_result_status CHECK (
|
||||
result_status IN ('processing', 'succeeded', 'failed')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_market_mcp_idempotency_client_key
|
||||
ON market_mcp_idempotency(client_id, idempotency_key);
|
||||
CREATE INDEX idx_market_mcp_idempotency_expiry ON market_mcp_idempotency(expires_at);
|
||||
|
||||
COMMIT;
|
||||
Reference in new issue
Block a user