memleketmeselesi/migrations/0003_issues.sql
Mukan Erkin 2498e75594 init: memleketmeselesi platform — API + migrations
FastAPI + PostgreSQL 16. KYC, issue sistemi, permission/group yönetimi,
session yönetimi, API client auth (kışla kapısı), officials/persons CRUD.
Migration 0001–0013 dahil.
2026-04-27 23:06:59 +03:00

86 lines
3.4 KiB
SQL

-- Sorun kategorileri
CREATE TABLE issue_categories (
id BIGSERIAL PRIMARY KEY,
parent_id BIGINT REFERENCES issue_categories(id) ON DELETE RESTRICT,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
icon TEXT
);
CREATE INDEX idx_issue_categories_parent ON issue_categories(parent_id);
-- Sorun durumu
CREATE TYPE issue_status AS ENUM (
'open', 'in_progress', 'resolved', 'rejected', 'duplicate'
);
-- Sorunlar
CREATE TABLE issues (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
body TEXT NOT NULL,
category_id BIGINT NOT NULL REFERENCES issue_categories(id),
location_id BIGINT NOT NULL REFERENCES locations(id),
reporter_id BIGINT NOT NULL REFERENCES users(id),
status issue_status NOT NULL DEFAULT 'open',
resolution_threshold SMALLINT NOT NULL DEFAULT 70, -- % çözüldü oyu eşiği
resolved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_issues_category ON issues(category_id);
CREATE INDEX idx_issues_location ON issues(location_id);
CREATE INDEX idx_issues_reporter ON issues(reporter_id);
CREATE INDEX idx_issues_status ON issues(status);
-- Sorun ↔ yetkili eşlemesi
CREATE TYPE assignment_source AS ENUM ('system', 'moderator', 'official_claim', 'ai');
CREATE TABLE issue_officials (
id BIGSERIAL PRIMARY KEY,
issue_id BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
person_id BIGINT REFERENCES persons(id) ON DELETE CASCADE,
org_id BIGINT REFERENCES organizations(id) ON DELETE CASCADE,
unit_id BIGINT REFERENCES administrative_units(id) ON DELETE CASCADE,
assigned_by assignment_source NOT NULL DEFAULT 'system',
confidence SMALLINT CHECK (confidence BETWEEN 0 AND 100),
assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT at_least_one_target CHECK (
person_id IS NOT NULL OR org_id IS NOT NULL OR unit_id IS NOT NULL
)
);
CREATE INDEX idx_issue_officials_issue ON issue_officials(issue_id);
CREATE INDEX idx_issue_officials_person ON issue_officials(person_id);
CREATE INDEX idx_issue_officials_unit ON issue_officials(unit_id);
-- Oylar
CREATE TYPE vote_value AS ENUM ('resolved', 'ongoing');
CREATE TABLE issue_votes (
id BIGSERIAL PRIMARY KEY,
issue_id BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
vote vote_value NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (issue_id, user_id)
);
CREATE INDEX idx_issue_votes_issue ON issue_votes(issue_id);
CREATE INDEX idx_issue_votes_user ON issue_votes(user_id);
-- Yorumlar
CREATE TABLE issue_comments (
id BIGSERIAL PRIMARY KEY,
issue_id BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
parent_id BIGINT REFERENCES issue_comments(id) ON DELETE CASCADE,
body TEXT NOT NULL,
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_issue_comments_issue ON issue_comments(issue_id);
CREATE INDEX idx_issue_comments_parent ON issue_comments(parent_id);